Compare commits

...

191 Commits

Author SHA1 Message Date
Tobias Ottenweller
d5d079bfcf Merge pull request #39 from craftinc/bugfix/serialization
fixed broken location/exit serialization of gates.
2017-01-01 19:19:13 +01:00
Tobias Ottenweller
3b16a6372b fixed broken location/exit serialization of gates. 2017-01-01 15:55:12 +01:00
Tobias Ottenweller
f20882e03a Merge pull request #38 from craftinc/feature/command_cleanup
Command cleanup
2017-01-01 15:29:44 +01:00
Tobias Ottenweller
c04aac10f6 bring back help page title. 2017-01-01 15:22:48 +01:00
Tobias Ottenweller
a38e12fbe6 still merging. 2017-01-01 15:20:28 +01:00
Tobias Ottenweller
8a199b4074 Merge branch 'development' into feature/command_cleanup
# Conflicts:
#	src/de/craftinc/gates/models/Gate.java
2017-01-01 15:16:35 +01:00
Tobias Ottenweller
ed5222e5fb Merge pull request #37 from craftinc/refactor/serialization_cleanup
Serialization cleanup
2017-01-01 15:12:08 +01:00
Tobias Ottenweller
1177d6e537 Merge pull request #36 from craftinc/refactor/cleanup2
Cleanup Part 2
2017-01-01 15:10:13 +01:00
Tobias Ottenweller
465533f4fe Added ability to define matrial for each gate seperatly. 2017-01-01 15:07:45 +01:00
Tobias Ottenweller
4c7f1201bd cleanup. 2017-01-01 13:28:58 +01:00
Tobias Ottenweller
64a7ac50fa Command cleanup. Stub commands for material and teleport added. 2017-01-01 13:27:07 +01:00
Tobias Ottenweller
aaf0002105 Removed LocationUtil: directly serialize locations. 2017-01-01 12:13:36 +01:00
Tobias Ottenweller
e34276b729 cleanup. 2017-01-01 11:47:38 +01:00
Tobias Ottenweller
ed32b23823 Fix teleporting players riding a vehicle. 2017-01-01 11:34:33 +01:00
Tobias Ottenweller
790fd5bccd bugfix: allow null gate parameter. 2017-01-01 10:52:13 +01:00
Tobias Ottenweller
acd96607d4 refactor permissions and packaging. 2017-01-01 10:52:00 +01:00
Tobias Ottenweller
96d9316b11 Merge pull request #35 from craftinc/refactor/cleanup2
Cleanup Part 2
2016-12-31 17:00:37 +01:00
Tobias Ottenweller
892f151e38 comments removed. 2016-12-31 15:58:02 +01:00
Tobias Ottenweller
3bc5ba500c Updated access modifiers, fixed all warnings. 2016-12-31 13:51:21 +01:00
Tobias Ottenweller
927b70fd2d Merge pull request #34 from craftinc/refactor/cleanup
Code formatting
2016-12-31 12:05:14 +01:00
Tobias Ottenweller
344e69cefd missing formatting for files. 2016-12-31 12:01:10 +01:00
Tobias Ottenweller
40b396f8a2 code formatter applied. 2016-12-31 11:59:11 +01:00
Mr Ddidderr
efb4b14b79 Merge pull request #32 from craftinc/feature/spigot
Spigot
2016-12-31 11:29:51 +01:00
Tobias Ottenweller
238dbe3e51 bump version to 2.4.1 2016-12-31 11:07:06 +01:00
Tobias Ottenweller
4deb8a3c6d updated dependencies. replaced bukkit with spigot 2016-12-31 11:04:49 +01:00
Tobias Ottenweller
e2903514fe read me updated. 2014-02-07 10:54:45 +01:00
Tobias Ottenweller
44e86059de Bumped version to 2.4.0 2014-02-05 20:48:58 +01:00
Tobias Ottenweller
fe0946117e Read me updated. 2014-02-05 20:48:37 +01:00
Tobias Ottenweller
43dd934f48 Docs updated. 2014-02-05 20:43:08 +01:00
Tobias Ottenweller
b37f1000ab Merge branch 'development' of github.com:craftinc/craftinc-gates into development 2014-02-05 20:36:34 +01:00
Tobias Ottenweller
c7a423ff20 Display information about allowed vehicles when executing the info command. 2014-02-05 20:36:23 +01:00
Tobias Ottenweller
b676af278d Display a not allowed while riding message. 2014-02-05 20:23:59 +01:00
Tobias Ottenweller
a579209037 Do call the exit changed method of the gates manager. 2014-02-05 20:16:16 +01:00
Tobias Ottenweller
ca74b2e3ed Removed invalid to do notes. 2014-02-05 20:15:56 +01:00
Tobias Ottenweller
6924e36249 Added soft-depend for multi-world plugins 2014-01-27 09:51:57 +01:00
Tobias Ottenweller
f8f31640ef Added gate change listener interface used for dynmap. 2014-01-26 14:29:28 +01:00
Tobias Ottenweller
c80b0f0f68 Fix not persistent allow/deny riding flag. 2014-01-19 21:01:28 +01:00
Tobias Ottenweller
2bd8b0ff03 Fixed broken migration for old storage versions. 2014-01-06 17:28:59 +01:00
Tobias Ottenweller
a613b1933a Send messages to players when executing allow/deny riding commands. 2014-01-06 17:21:43 +01:00
Tobias Ottenweller
d8fff26c9e Added a allow riding attribute to the gate class. Added code to guaranty compatibility. Added two new commands for setting the riding attribute. 2014-01-06 17:13:02 +01:00
Tobias Ottenweller
0c13d0d3e3 Fix for missing clone of pig attributes. 2013-12-29 09:51:26 +01:00
Tobias Ottenweller
29592823b6 Bumped version to 2.4.0-DEV 2013-12-29 09:50:14 +01:00
Tobias Ottenweller
56c6af02b1 Keep velocity when teleporing boats and minecarts. This commit completes issue #10 2013-12-28 16:43:18 +01:00
Tobias Ottenweller
8b873a6d60 Added support for vehicles. 2013-12-28 15:11:12 +01:00
Tobias Ottenweller
e36519c246 gitignore updated. 2013-12-28 15:10:30 +01:00
Tobias Ottenweller
125d327a0d Updated bukkit dependency. 2013-12-28 10:25:09 +01:00
Tobias Ottenweller
6c8658f7c5 Fixed typo. Did some cleanup. 2013-12-28 10:24:55 +01:00
Tobias Ottenweller
14041f8cd7 Updated bukkit dependency to 1.7.2-R0.1-SNAPSHOT. 2013-12-08 16:21:18 +01:00
Tobias Ottenweller
bb4a41e782 Readme updated. #2 2013-11-26 09:21:01 +01:00
Tobias Ottenweller
82df684c22 Readme updated. 2013-11-26 09:16:14 +01:00
Tobias Ottenweller
7f89917e81 Updated version to 2.3.0. 2013-11-24 12:55:47 +01:00
Tobias Ottenweller
a1cb0102f8 Changed the executing phase of deployment script. 2013-11-23 15:31:27 +01:00
Paul Schulze
5af520f8ea include mcstats in jar file when packaging with maven 2013-11-23 15:11:13 +01:00
Tobias Ottenweller
28cacfdb19 Updated the changelog and other documents for the upcoming 2.3 release. 2013-11-16 17:54:33 +01:00
Tobias Ottenweller
757d6b5a48 readme updated. 2013-11-16 15:40:53 +01:00
Tobias Ottenweller
056b8896a6 Updated bukkit depency. 2013-11-16 15:40:45 +01:00
Tobias Ottenweller
12a0bba6cc Print the names of nearby gates when executing /gate nb.
Fixed a serious bug when trying to print a very long title.
Made the info command work without a supplied gate id. It then will print information about the closest gate. (Issue #13)
2013-09-17 17:57:31 +02:00
Tobias Ottenweller
e9a454182a Added the ability to change gate block types. Issue #26.
Refactoring: Added a ConfigurationUtil class. Moved all configuration keys into it.
2013-09-15 17:09:17 +02:00
Tobias Ottenweller
260cabc509 Small typo fix. 2013-08-07 16:40:59 +02:00
Tobias Ottenweller
0b29936958 Changed some text getting displayed while executing the info command. 2013-07-27 12:03:38 +02:00
Tobias Ottenweller
efc30d0ae0 Added the nearby command. Issue #12 2013-07-24 10:39:37 +02:00
Tobias Ottenweller
f4111fb34f Added a URL and license to the pom file. 2013-07-21 19:29:12 +02:00
Tobias Ottenweller
37bce23e3d Updated a description inside the plugin.yml. 2013-07-18 12:09:50 +02:00
Tobias Ottenweller
d5ff63c163 Added Plugin Metrics. 2013-07-16 12:09:20 +02:00
Tobias Ottenweller
e60c735153 Removed the .settings folder. 2013-07-16 12:08:24 +02:00
Tobias Ottenweller
013fad2b95 Added a license header to the exitopen command class. 2013-07-11 22:35:55 +02:00
Tobias Ottenweller
5ace80e6d1 Added an exitopen command. This command will set the exit location of a gate and open it afterwards. 2013-07-11 22:35:01 +02:00
Tobias Ottenweller
42b293e6bc Updated the pom file:
* Updated (craft-) bukkit dependencies to 1.6.2-R0.1-SNAPSHOT
* Bumped version 2.3.0-DEV
2013-07-11 22:33:38 +02:00
Tobias Ottenweller
54545a9ee1 Updated the change log. 2013-07-10 22:14:55 +02:00
Tobias Ottenweller
560bbf0394 Updated the pom file for version 2.2.1 2013-07-10 22:02:19 +02:00
Tobias Ottenweller
2150cc66d0 Changed the event priority of the player teleport listener to MONITOR. 2013-07-10 22:02:05 +02:00
Tobias Ottenweller
7673c3f674 Changed to event priority of the block break listener to MONITOR. This will resolve issues with third party protection plugins. See issue #25. 2013-07-10 20:43:52 +02:00
Tobias Ottenweller
577531db5e Updated the pom file for version 2.2.0 2013-07-06 17:14:11 +02:00
Tobias Ottenweller
3739ee6c5a Added a toString method to the SimpleLocation class. 2013-07-06 17:13:46 +02:00
Tobias Ottenweller
2d830b2f9f Fixed a bug where players got teleported at the old location of a gate when a new location has been set. 2013-07-06 17:13:28 +02:00
Tobias Ottenweller
02fd7a4916 Added missing whitespace character. 2013-07-06 15:42:29 +02:00
Tobias Ottenweller
e21089d8c7 Removed a newline character. 2013-07-04 12:47:28 +02:00
Tobias Ottenweller
fc488e7f31 Remove portal blocks at the old location of a gate when setting a new location. 2013-07-04 10:19:57 +02:00
Tobias Ottenweller
e8f23078f1 Check for case insensitivity while loading gates from disk. 2013-07-04 10:08:59 +02:00
Tobias Ottenweller
9ec2b91181 Typo fix. 2013-07-01 20:46:23 +02:00
Tobias Ottenweller
478095190a Added newlines toe the change log. 2013-07-01 13:50:02 +02:00
Paul Schulze
17942caa73 README.md: fixed some typos 2013-07-01 13:30:09 +02:00
Tobias Ottenweller
d0c23b581a Fixed some typos inside the readme file. 2013-06-30 13:36:56 +02:00
Tobias Ottenweller
6884f43e50 Documentation and readme updated. 2013-06-29 12:19:12 +02:00
Tobias Ottenweller
e84130a8fe Better handling for players entering a gate with their head only. 2013-06-26 12:28:30 +02:00
Tobias Ottenweller
8f54c0acc2 Moved gate validation from saving to loading. This hopefully resolves issues with gates getting closed on save. 2013-06-24 20:42:40 +02:00
Tobias Ottenweller
aeae14e2a0 Added a option for saving gates after every change. 2013-06-24 09:50:49 +02:00
Tobias Ottenweller
36be95d0f5 Gate: Added final statement to arguments. Better handling for case insensitivity. 2013-06-24 09:44:44 +02:00
Tobias Ottenweller
ed4dd5711e Make gate ids case insensitive. 2013-06-23 20:14:19 +02:00
Tobias Ottenweller
437296262c Cleanup 2013-06-23 20:13:53 +02:00
Tobias Ottenweller
ec2caaad97 Removed debug prints. 2013-06-23 19:55:03 +02:00
Tobias Ottenweller
81daa83f44 code cleanup. 2013-06-23 19:26:13 +02:00
Tobias Ottenweller
0695b3e202 Improved error messages when setting a gate location. 2013-06-23 19:09:20 +02:00
Tobias Ottenweller
6df27c14a0 Bugfix: portal blocks don't get set when unhiding a gate. 2013-06-23 19:04:07 +02:00
Tobias Ottenweller
a16d847234 Better print out for creating gates a invalid locations. 2013-06-23 18:48:18 +02:00
Tobias Ottenweller
d24f0b8fd1 Bugfix: new gates do not work when opening them. 2013-06-23 18:47:17 +02:00
Tobias Ottenweller
ea52e4d87e Also check for the players head locations when trying to teleport the player. 2013-06-23 18:46:03 +02:00
Tobias Ottenweller
f4495240a5 Remove and add gates to the gate attributes. 2013-06-23 18:43:22 +02:00
Tobias Ottenweller
09b9c65ef6 Added some prints for debugging. 2013-06-23 18:07:18 +02:00
Tobias Ottenweller
afe693d491 Bugfix: remove portal blocks when deleting a gate. 2013-06-23 17:27:57 +02:00
Tobias Ottenweller
d4f33a1885 Do not cast to Double. Rather use Number. 2013-06-23 17:14:51 +02:00
Tobias Ottenweller
b50a2b27d3 Bugfix: do not let the location command fail if previous location was invalid. 2013-06-23 17:09:39 +02:00
Tobias Ottenweller
e88e03ed42 Removed a debug print. 2013-06-23 17:08:44 +02:00
Paul Schulze
53e2be6be7 Bugfix: Only check distance between players in the same world! 2013-06-23 15:32:33 +02:00
Tobias Ottenweller
d29ad9a474 Removed some debug prints. 2013-06-21 21:36:47 +02:00
Tobias Ottenweller
4f89e20e6f Print reason when closing gate on save. 2013-06-20 23:07:10 +02:00
Tobias Ottenweller
563bdfe2fd Updated the change log. 2013-06-20 22:36:03 +02:00
Tobias Ottenweller
931cd1a520 Updated the build scripts. Bumped version to 2.2.0-beta. 2013-06-20 22:35:46 +02:00
Tobias Ottenweller
b64f41ce0c Do not log "enabled" when gate storage file is corrupted. 2013-06-20 19:58:34 +02:00
Tobias Ottenweller
1e9b9905a5 Disable the plugin if storage migration is not possible. 2013-06-20 19:19:00 +02:00
Tobias Ottenweller
d28bedb78e Better handling for invalid gate storage files. 2013-06-19 17:18:35 +02:00
Tobias Ottenweller
e9c4583c3d Updated command classes to use better shortcut commands. (Issue #21) 2013-06-19 17:17:56 +02:00
Tobias Ottenweller
7a8e61104a Disable the plugin if the gate storage file is corrupted. 2013-06-19 14:25:31 +02:00
Tobias Ottenweller
c764850ded Declared many arguments as final inside the GatesManager class. 2013-06-19 14:08:27 +02:00
Tobias Ottenweller
f939e27464 Added a delayed block changes sending method. 2013-06-19 14:03:50 +02:00
Tobias Ottenweller
ecd219fb2d Added parameter checks and final attributes to the FloodUtil class. 2013-06-19 13:42:16 +02:00
Tobias Ottenweller
99be2905be Added checks for broken gate frame blocks. 2013-06-18 19:53:04 +02:00
Tobias Ottenweller
9e36cf189b Added a configuration file. Made various classes read from the configuration. 2013-06-17 14:32:49 +02:00
Tobias Ottenweller
78283a4f34 Send block changes on command execution. 2013-06-15 15:33:01 +02:00
Tobias Ottenweller
1d08c79cff Check for non existing gate list while loading gates from disk. 2013-06-15 13:33:19 +02:00
Tobias Ottenweller
cb0dec8b83 More distant portal blocks now get send to players. 2013-06-12 21:58:01 +02:00
Tobias Ottenweller
1968ccaaeb Added an authors file. Added a license section the each source file. 2013-06-05 13:00:29 +02:00
Tobias Ottenweller
d23a9b7650 Added basic gate block sending mechanism. 2013-06-03 19:14:56 +02:00
Tobias Ottenweller
e5ef266f04 Refactoring: created new packages. 2013-06-03 16:37:20 +02:00
Tobias Ottenweller
724e05e0a4 code and comment cleanup. 2013-06-03 16:19:51 +02:00
Tobias Ottenweller
b18df58870 Refactoring of the LocationUtil class. 2013-06-03 16:09:26 +02:00
Tobias Ottenweller
7119c185e7 Version bump to 2.2.0-DEV 2013-06-01 15:07:03 +02:00
Tobias Ottenweller
c740a5b111 Fixed a bug where gates did not work after chaining it's location. 2013-06-01 15:02:22 +02:00
Tobias Ottenweller
8bee74df89 Code cleanup. 2013-06-01 15:01:59 +02:00
Tobias Ottenweller
b383ff89c6 Cleanup 2013-06-01 14:50:39 +02:00
Tobias Ottenweller
fec999541e Removed the ChunkLoadListener. 2013-06-01 14:45:47 +02:00
Tobias Ottenweller
2ed611d995 Only teleport players once if they got pending teleport requests. 2013-06-01 12:43:39 +02:00
Tobias Ottenweller
faabb2f9db Testing code for not working chunk load listener. 2013-06-01 12:29:28 +02:00
Tobias Ottenweller
e6e6273147 Made chunk load listener handle multiple teleport requests with the same destination chunk. 2013-06-01 11:32:18 +02:00
Tobias Ottenweller
093778f2fb Added missing TeleportRequest class. 2013-05-26 14:52:15 +02:00
Tobias Ottenweller
a5b34458c4 Make sure chunks are loaded before teleporting players. 2013-05-26 14:52:04 +02:00
Tobias Ottenweller
30d15c141e Refactored the Gate class: removed the fill and empty methods. 2013-05-26 14:03:18 +02:00
Tobias Ottenweller
3cac4e70cc Allow bigger portals. Portals cannot be made of portal blocks anymore. 2013-05-26 13:08:50 +02:00
Tobias Ottenweller
95446f1371 Throw an exception when the gates got stored with a newer version. 2013-05-26 13:03:22 +02:00
Tobias Ottenweller
8e860e90c6 code style. 2013-05-26 12:36:43 +02:00
Tobias Ottenweller
d9194c7497 Added a storage migration class. 2013-05-26 12:36:25 +02:00
Tobias Ottenweller
c3a24a940f Don't print block locations inside the info command. #2 2013-05-19 12:04:03 +02:00
Tobias Ottenweller
c62fb32e90 Don't print block locations inside the info command. 2013-05-19 12:03:45 +02:00
Tobias Ottenweller
580fda0273 Don't teleport if gates are closed. 2013-05-19 12:01:55 +02:00
Tobias Ottenweller
252292819f Removed an unused method. 2013-05-19 12:01:34 +02:00
Tobias Ottenweller
79dcd259dc Always use block locations when creating SimpleLocations to prevent offsets when comparing player and block locations. 2013-05-19 12:01:18 +02:00
Tobias Ottenweller
12fde472a2 Fixed a typo. 2013-05-19 12:00:07 +02:00
Tobias Ottenweller
be3c541845 code style. 2013-05-19 11:59:47 +02:00
Tobias Ottenweller
6bd53a3fe6 Fixed typos. 2013-05-19 10:39:23 +02:00
Tobias Ottenweller
a9be1eaa51 Updated the test-deployment script. Keep the version inside the filename. 2013-05-19 10:38:48 +02:00
Tobias Ottenweller
dd492a7327 updated the test-deployment script. 2013-05-19 10:06:27 +02:00
Tobias Ottenweller
0230314c7e Added a little bit more logging. 2013-05-19 10:05:21 +02:00
Tobias Ottenweller
768d385915 Renamed PluginPlayerListener to PlayerMoveListener 2013-05-18 19:56:10 +02:00
Tobias Ottenweller
232305a871 Added some checks for null values to the GatesManager class. 2013-05-18 19:55:20 +02:00
Tobias Ottenweller
00573c2763 Added some documentation to the Gate class. 2013-05-18 19:54:43 +02:00
Tobias Ottenweller
f1d623df60 Fixed a typo. 2013-05-18 19:54:17 +02:00
Tobias Ottenweller
040377cb36 Refactoring and code cleanup. 2013-05-18 11:26:45 +02:00
Tobias Ottenweller
e9027900ce Refactored the BaseCommand class. 2013-05-18 11:11:10 +02:00
Tobias Ottenweller
34b1c7e0ce Removed the 'h' shortcut. 2013-05-17 21:58:05 +02:00
Tobias Ottenweller
987de39bf9 Merge branch 'master' of github.com:craftinc/craftinc-gates into development
Conflicts:
	pom.xml
	src/de/craftinc/gates/BaseGate.java
	src/de/craftinc/gates/commands/BaseCommand.java
	src/de/craftinc/gates/commands/CommandCreate.java
	src/de/craftinc/gates/commands/CommandList.java
2013-05-17 21:54:15 +02:00
Tobias Ottenweller
0e13f60122 Fixer a typo. 2013-05-17 21:28:56 +02:00
Tobias Ottenweller
f2bfe27eba Removed debug print. 2013-05-17 21:24:57 +02:00
Tobias Ottenweller
7f8b8eee0f updated pom.xml to version 2.1.2 2013-05-17 21:14:36 +02:00
Tobias Ottenweller
e0b30135cc Removed duplicate log message. 2013-05-17 21:14:19 +02:00
Paul Schulze
1056fbf969 updated pom.xml 2013-05-17 21:10:34 +02:00
Tobias Ottenweller
916dc1b3a1 Updated changelog. 2013-05-17 21:05:36 +02:00
Tobias Ottenweller
4b7fff2277 Fixed some typos 2013-05-17 20:53:36 +02:00
Tobias Ottenweller
ed2683affc Fixed issue #18. Gates with 'null' as location did cause exceptions at many locations. 2013-05-17 20:13:49 +02:00
Paul Schulze
cac6eb6022 Fixed bug: When x or z was negative a player was teleported one block
beside the real portal blocks.
2013-05-16 09:55:12 +02:00
Tobias Ottenweller
67c8a15e46 Merge branch 'development' of github.com:craftinc/craftinc-gates into development 2013-05-16 09:53:29 +02:00
Tobias Ottenweller
a984f3a3ea Updated README.md 2013-05-16 09:53:24 +02:00
Tobias Ottenweller
f253dd4ccc Refactored the GatesManager. Added SimpleChunk and SimpleLocation classes. Made PluginPlayerListener use the gateByLocation method of the GatesManager. 2013-05-14 20:05:25 +02:00
Paul Schulze
71031d0578 Fixed bug: When x or z was negative a player was teleported one block
beside the real portal blocks.
2013-05-13 17:48:09 +02:00
Paul Schulze
e30b82b74f added bukkit-testserver to gitignore
scripts for automatic bukkit-testserver handling
2013-05-13 17:33:27 +02:00
Paul Schulze
acf4c9002c updated pom.xml 2013-05-13 17:32:50 +02:00
Tobias Ottenweller
4012a4ac15 Started working on issue #16:
* Replaced the Gate class with a GateManager class.
* Created HashMap structures to effectively query for gates.
* Refactored to get the plugin running.

Optimizations are not yet in place! Further work is necessary.
2013-05-08 20:30:43 +02:00
Tobias Ottenweller
8c6718d13f Removed unused imports. 2013-04-09 09:11:32 +02:00
Tobias Ottenweller
6a34d44f20 Updated change log and plugin.yml. 2013-04-09 09:11:22 +02:00
Tobias Ottenweller
b196c53335 Display messages about disallowed usage of gates less frequent. 2013-04-08 21:32:15 +02:00
Tobias Ottenweller
d54fd7f72e Removed some debug code. 2013-04-08 21:09:15 +02:00
Tobias Ottenweller
cede47deab Rewrite of the list command. 2013-04-08 21:08:08 +02:00
Tobias Ottenweller
1ef178f6a0 Updated class path. (CraftBukkit 1.5.1 R0.1) 2013-04-07 19:33:07 +02:00
Tobias Ottenweller
802f8c07e3 Merge branch 'master' of github.com:craftinc/craftinc-gates into development 2013-04-06 12:08:21 +02:00
Tobias Ottenweller
a8a95af497 Further refactoring of the list command. 2013-04-06 12:08:09 +02:00
Tobias Ottenweller
0af3631693 Removed unused imports. 2013-04-06 12:07:57 +02:00
Tobias Ottenweller
4d40b140fa Start work on refactoring the list command. 2013-04-05 21:51:18 +02:00
Tobias Ottenweller
8830355216 Updated the change log. 2013-03-26 20:59:18 +01:00
Tobias Ottenweller
3481c2a10f Bumped version to 2.1.0 2013-03-26 20:53:21 +01:00
Tobias Ottenweller
a319f793b2 Removed unused import. 2013-03-26 20:52:10 +01:00
Tobias Ottenweller
6373f98894 Removed debug prints. 2013-03-26 20:49:48 +01:00
Tobias Ottenweller
e49c5c0acb Updated classpath file. 2013-03-26 20:49:29 +01:00
66 changed files with 3926 additions and 2449 deletions

View File

@ -1,12 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="src" path="src"/> <classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="lib" path="/Users/tobi/Code/craftbukkit-1.4.5-R1.0.jar" sourcepath="//Users/tobi/Code/Bukkit">
<attributes>
<attribute name="source_encoding" value="UTF-8"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="/Users/tobi/Code/Vault.jar"/> <classpathentry kind="lib" path="/Users/tobi/Code/Vault.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="/Users/tobi/Code/craftbukkit-1.5.1-R0.1.jar"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>

6
.gitignore vendored
View File

@ -27,4 +27,8 @@ target/
profile profile
# bukkit # bukkit
bukkit/ bukkit/
# bukkit test-server
bukkit-testserver/
dependency-reduced-pom.xml

View File

@ -1,12 +0,0 @@
#Wed Apr 06 16:59:25 CEST 2011
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

13
AUTHORS.txt Normal file
View File

@ -0,0 +1,13 @@
The following persons contributed to Craft Inc. Gates (previously named Ancient Gates):
CURRENT MAINTAINERS
Tobias Ottenweller <mail@ottenweller.net>
Paul Schulze <info@paul-schulze.de>
FORMER CONTRIBUTORS (alphabetical order)
Jacob Brunson <jacob@dimensionsmachine.com>
locutus <bladedpenguin@gmail.com>
Olof Larsson <olof@sylt.nu>

120
README.md
View File

@ -1,107 +1,85 @@
# Craft Inc. Gates Easily create portals with custom design # Craft Inc. Gates #
(previously known as __AncientGates__) This awesome plugin lets you _travel_ to far away places and worlds _faster than light_! Just create a gate at any location and set an exit somewhere else.
With this plugin players can create gates that will teleport anyone who enter the gate to specific a location. This has been made available by the hard work of the research and development department of the _Craft Inc. Corporation_. Under the lead of Professor Ddidderr Craftman scientists worked years to find a way to bend time and space inside the Minecraft universe to enable _ultra fast transportation_.
The hightlights are: __It is so darn easy to use!__ and __The gates can look any way you like__
Try the ingame command: __/gate__ Now it is time for _you_ to try out this wonderful plugin. Simply install, create a gate and feel the funny tickle inside your brain while traveling.*
Also have a look at the full __[userguide](http://www.craftinc.de/blog/?p=255)__. The key features of this are:
Check out our **[Craft Inc. Minecraft Server](http://www.craftinc.de)**! Everyone is welcome! * Dynmap integration
* Gates with and without frames
Thought first you should take a look at the demonstration oloflarsson and karibu6 created: * Gates consisting of portal blocks and gates made of air (so called hidden gates)
__[http://www.youtube.com/watch?v=L4hyqTpeEaA](http://www.youtube.com/watch?v=L4hyqTpeEaA)__ * Gates with destinations in different worlds
* Gates with custom shapes (gates can look any way you want)
* Riding through gates
## FAQ *The Craft Inc. Corporation won't take any responsibility for seasickness, memory loss and sudden suffocation in walls while traveling with one of our gates!
## FAQ ##
__Who can create a gate?__ __Who can create a gate?__
See the _Permissions_ section. Have a look at the [_Permissions_](http://dev.bukkit.org/bukkit-plugins/craftinc-gates/pages/permissions/) page.
__Who can destroy a gate?__ __Who can destroy a gate?__
Anyone if you do not use a third-party protection plugin like Grief Prevention. Anyone if you do not use a third-party protection plugin like Grief Prevention.
__Are there IConnomy integration, Features for user to dial other gates etc?__ __Is there a IConnomy integration? Features for user to dial other gates etc?__
Nope. This plugin is very minimalistic and plain. Server operators manage the portals players use them any time they are open. Nope. We currently don't plan to integrate such features. If you really need such an integration please inform us. If there are a lot of people requesting such features we might change our mind.
## Usage __Is there a list of all commands?__
__Note that the commands mentioned in this section will be made available with the upcoming 2.1 release of Craft Inc. Gates! Meanwhile type '/gate help' while playing to see the current set of commands.__ Sure, type _/gate help_ in-game or have a look at the [_Commands_](http://dev.bukkit.org/bukkit-plugins/craftinc-gates/pages/commands/) page.
With the __/gate__ plugin you can create gates which will teleport players anywhere you want. Just build a portal (like those nether portal). The gates can look any way you like. __When I destroy the frame of a gate it stops working. Shouldn't it still work?__
To make the gate work place yourself in a newly created gate frame and type __/gate create [id]__. Afterwards walk to the destination of your portal and type __/gate exit [id]__ to set the destination. With __/gate open [id]__ you can get your newly created gate to work. Yes and no. To make gates work without a frame you need to tweak the _checkForBrokenGateFrames_ setting. Have a look at the [_Configuration_](http://dev.bukkit.org/bukkit-plugins/craftinc-gates/pages/configuration/) page for more information.
To hide a gate simply call __/gate hide [id]__. Now that gate wont have purple blocks when open. You can even remove the frame without stopping the hidden gate from working. But unhiding a gate without a frame is not possible!
Use the following commands to modify your gates even further: ## Usage ##
With this plugin you can create gates which will teleport players anywhere you want. The gates can look any way you like.
* __/gate close,c [id]__ To make the gate work place yourself inside a newly created gate frame and type __/gate new [id]__. Afterwards walk to the destination of your gate and type __/gate exit [id]__ to set the destination. With __/gate open [id]__ you can get your newly created gate to work.
Closes a gate to prevent players from using it.
* __/gate create,new [id]__ To hide a gate simply call __/gate hide [id]__. Now that gate wont be made of purple portal blocks while open.
Creates a gate at your current location.
* __/gate delete,del,remove,rm [id]__ Have a look at the [_Commands_](http://dev.bukkit.org/bukkit-plugins/craftinc-gates/pages/commands/) page to find out how to modify gates even further.
Removes the gate from the game.
* __/gate exit,e [id]__
Changes the location where the gate will teleport players to your current location.
* __/gate help,h,? [page]__
Prints the help pages
* __/gate hide,h [id]__
Makes a gate NOT consist of gate blocks while open.
* __/gate info,details,i,d [id]__
Prints detailed informations about a certain gate.
* __/gate list,ls [page]__
Prints all availiable gates.
* __/gate location,l [id]__
Sets the entrance of the gate to your current location.
* __/gate open,o [id]__
Open a gate so players can use it.
* __/gate rename,changename,cn [current name] [new name]__
Changes the name/id of the gate.
* __/gate unhide,uh [id]__
Makes that gate visible.
## Installing ##
## Permissions 1. Download the latest release _[here](http://dev.bukkit.org/bukkit-plugins/craftinc-gates/files/)_
2. Delete any old versions of _Craft Inc. Gates_ (only the .jar files) including the extra dynmap-plugin of this plugin.
3. Extract the content of the zip file into the plugins folder of your Bukkit server.
4. Start or reload the server.
* __craftincgates.info__ ## Craft Inc. ##
Gives access to info and list commands. Check out our __[Craft Inc. Minecraft Server](http://www.craftinc.de)__. Everyone is welcome!
* __craftincgates.use__ Also check out our other great plugins:
Allows you to travel via gates.
* __craftincgates.manage__ * [__Craft Inc. BorderProtection__](http://dev.bukkit.org/bukkit-mods/craftinc-borderprotection/)
Gives access to commands manipulating gates. protect your worlds with a border players cannot cross.
## Installing * [__Craft Inc. Replicator__](http://dev.bukkit.org/bukkit-mods/craftinc-replicator/)
allows players to build a replicator to replicate blocks and other items. (still experimental)
1. Download the latest release: __[http://dev.bukkit.org/server-mods/craftinc-gates/files/](http://dev.bukkit.org/server-mods/craftinc-gates/files/)__ * __Craft Inc. Scarecrow__
2. Put the downloaded _CraftIncGates.jar_ in the plugins folder. coming soon!
3. Start or reload the server.
## Bugs and other Problems ## Roadmap ##
* Per player permissions for using and managing gates.
* Horizontal gates.
Please use our [issue tracker](https://github.com/craftinc/craftinc-gates/issues?milestone=1&state=open) on github. ## Bugs and other Problems ##
Please use our [_issue tracker_](https://github.com/craftinc/craftinc-gates/issues?state=open) on GitHub.
## Legal Information ##
## License This project is a fork of the original [_Ancient Gates_](https://github.com/bladedpenguin/minecraft-ancient-gates). It is licensed under the [_LGPL_](http://www.gnu.org/licenses/lgpl-3.0.txt) just like the Bukkit project. Thanks to all current and previous [_contributors_](https://github.com/craftinc/craftinc-gates/blob/development/AUTHORS.txt).
The font used for the Craft Inc. Gates logo is called [_MineCrafter 3_](http://www.minecraftforum.net/topic/892789-minecrafter-3-font-simply-easy/) and has been made available under the creative commons license. Thanks to Asherz08, MadPixel and Ashley Denham for this great font.
This project has a LGPL license just like the Bukkit project. This plugin utilizes [_Hidendra's plugin metrics system_](http://mcstats.org), which means that the following information is collected and sent to mcstats.org: a unique identifier, the server's version of Java, whether the server is in offline or online mode, the plugin's version, the server's version, the OS version/name and architecture, the core count for the CPU, the number of players online, the Metrics version. __You can disable the stat collection via /plugins/PluginMetrics/config.yml if you wish.__

View File

@ -1,4 +1,37 @@
## 2.1.0 (not yet released) ## 2.4.0 ##
* Resolved issues with closing gates (special thanks to THCFrosD)
* Added support for riding through gates (with horses, mine carts, pigs and boats)
* Dynmap integration (extra plugin)
## 2.3.0 ##
* Added a command for setting the exit and opening a gate at once.
* Enabled the ability to change the gate block material.
* Added a command printing all nearby gates while highlighting them.
* Changed the info command to highlight gates.
* Updated the info command to print information about the nearest gate if no gate name got supplied.
## 2.2.1 ##
* Changed priority of some event listeners to solve problems with WorldGuard and other protection plugins.
## 2.2.0 ##
* Improved gate commands and shortcuts (have a look at the bukkit-dev page for more information).
* Improved overall performance.
* Added a configuration file (have a look at the bukkit-dev page for more information).
* Resolved issues with (random) teleports to the nether.
* Made it possible to create non hidden gates without a frame. (Turned off by default!)
* Changed the behavior regarding portal blocks. Starting with this version no blocks will be set by the plugin. All portal blocks will only be visible on client side.
* Added checks preventing the plugin from overwriting the gate storage file on error.
* Added the ability to change and disable messages on teleport and insufficient permissions via a config file.
## 2.1.2 ##
* Fixed a bug where players got teleported one block beside the real portal.
* Fixed a bug where gates with no location caused multiple exceptions.
## 2.1.1 ##
* Made the list command more reliable.
* Error messages will be displayed less frequent.
## 2.1.0 ##
* Command outputs are now colored. * Command outputs are now colored.
* Fixed a bug where players in creative mode would not be teleported correctly. * Fixed a bug where players in creative mode would not be teleported correctly.
* Made various commands available via the server console. * Made various commands available via the server console.

47
doc/Commands.md Normal file
View File

@ -0,0 +1,47 @@
* __/gate allowRiding, ar [id]__
Update a gate so players can travel through it while riding.
* __/gate close, c [id]__
Closes a gate to prevent players from using it.
* __/gate denyRiding, dr [id]__
Update a gate so players can NOT travel through it while riding.
* __/gate delete, del, remove [id]__
Removes the gate from the game.
* __/gate exit, e [id]__
Changes the location where the gate will teleport players to your current location.
* __/gate exitopen, eo [id]__
Changes the location where the gate will teleport players to your current location. Also tries to open that gate afterwards.
* __/gate help, ? [page]__
Prints help pages.
* __/gate hide, h [id]__
Makes a gate NOT consist of gate blocks while open.
* __/gate info, i [id]__
Prints details about a certain gate. Will print information about the nearest gate if no _id_ is supplied. Also highlights the gate you're requesting information about.
* __/gate list, ls [page]__
Prints all available gates.
* __/gate location, lo [id]__
Sets the entrance of the gate to your current location.
* __/gate nearby, nb__
Prints the name of nearby gates. Also highlights them.
* __/gate new, n [id]__
Creates a gate at your current location.
* __/gate open, o [id]__
Open a gate so players can use it.
* __/gate rename, rn [current name] [new name]__
Changes the name/id of the gate.
* __/gate unhide,uh [id]__
Makes that gate visible.

57
doc/Configuration.md Normal file
View File

@ -0,0 +1,57 @@
Starting with version 2.2.0 some features are customizable via a configuration file.
The configuration file will be automatically created on the the first startup after
installing or updating the plugin.
The following keys and values are available:
* __maxGateBlocks__
A positive integer defining the maximum number of blocks a gate can consist of.
Note that increasing this value might slow down your server!
* __playerGateBlockUpdateRadius__
Defines the radius around a player where portal blocks are visible to that player.
Adjust this value when increasing or decreasing the view-distance on the server.
Only positive integer values are allowed.
* __checkForBrokenGateFrames__
Allowed values are _true_ and _false_ only. Setting this value to _false_ will disable
all checks for broken frames for non-hidden gates. Disabling frame block checks
might increase you server performance.
* __saveOnChanges__
Allowed values are _true_ and _false_ only. Disabling _save on changes_ might
increase server performance but gates will only be saved to disk when the plugin
gets disabled! This might lead to data loss on error.
* __gateTeleportMessage__
A string value going to displayed every time when a player travels using a gate. Will
only be displayed if _showTeleportMessage_ is set to _true_.
* __showTeleportMessage__
A boolean (_true_ or _false_) determining wether the _teleport message_ will
be displayed.
* __gateTeleportNoPermissionMessage__
A string value going to displayed every time when a player enters a gate and is not allowed to use that gate. Will only be displayed if _showTeleportNoPermissionMessage_
is set to _true_.
* __gateTeleportVehicleNotAllowedMessage__
A string value being displayed when a player tries to go through a gate while riding when riding through this gate is disabled. Will only be displayed if _showTeleportNoPermissionMessage_ is set to _true_.
* __showTeleportNoPermissionMessage__
A boolean (_true_ or _false_) determining wether the _no permission message_ will
be displayed.
* __gateMaterial__
A String representing the material all gates will consist of. Have a look at our [_Gate Material Page_](http://dev.bukkit.org/bukkit-plugins/craftinc-gates/pages/gate-materials/) for all possible values.

27
doc/Gate Materials.md Normal file
View File

@ -0,0 +1,27 @@
Starting with version 2.3.0 different gate materials can be used. You can set them via the configuration file. The following Materials are currently defined:
* sapling
* water
* lava
* cobweb
* grass
* dead bush
* dandelion
* poppy
* brown mushroom
* red mushroom
* torch
* redstone torch (off)
* redstone torch (on)
* fence
* nether portal
* iron bars
* glass pane
* fence gate
* nether brick fence
* nether wart
* end portal
* cobblestone wall
Your favorite material is missing? Please contact us and we will see if we can add it.

12
doc/Permissions.md Normal file
View File

@ -0,0 +1,12 @@
The following permissions are available: (Also have a look at the [Commands Page](http://dev.bukkit.org/bukkit-plugins/craftinc-gates/pages/commands/) to see if which commands can be executed with which permission set.)
* __craftincgates.info__
Gives access to info and list commands.
* __craftincgates.use__
Allows you to travel via gates.
* __craftincgates.manage__
Gives access to commands manipulating gates.
Craft Inc. Gates will use __[Vault](http://dev.bukkit.org/bukkit-mods/vault/)__'s permission system if Vault is installed on your server.

View File

@ -1,10 +1,10 @@
name: Craft Inc. Gates name: ${project.name}
version: 2.1.0-beta version: ${project.version}
description: A plugin to create gates for fast traveling. description: A plugin to create gates for fast traveling.
softdepend: [Vault] softdepend: [Vault, Multiverse-Core, MultiWorld, RoyalCommands]
author: tomco, s1m0ne author: tomco, s1m0ne
authors: [oloflarsson, locutus, DrAgonmoray, s1m0ne, tomco] authors: [oloflarsson, locutus, DrAgonmoray, s1m0ne, tomco]
website: http://www.craftinc.de/craftinc-gates/ website: http://dev.bukkit.org/bukkit-plugins/craftinc-gates/
main: de.craftinc.gates.Plugin main: de.craftinc.gates.Plugin
database: false database: false
@ -16,7 +16,7 @@ commands:
permissions: permissions:
craftincgates.*: craftincgates.*:
description: Gives access to all ancient gates commands and lets you use open gates. description: Gives access to all Craft Inc. Gates commands.
children: children:
craftincgates.info: true craftincgates.info: true
craftincgates.use: true craftincgates.use: true

142
pom.xml
View File

@ -4,50 +4,146 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>de.craftinc</groupId> <groupId>de.craftinc</groupId>
<artifactId>CraftIncGates</artifactId> <artifactId>CraftIncGates</artifactId>
<name>Craft Inc. Gates</name>
<url>http://dev.bukkit.org/bukkit-plugins/craftinc-gates/</url>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>1.1.1</version> <version>2.4.1</version>
<properties> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties> </properties>
<dependencies> <!-- License -->
<dependency> <licenses>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId> <license>
<version>RELEASE</version> <name>GNU Lesser General Public License Version 3</name>
<type>jar</type> <url>https://www.gnu.org/licenses/lgpl-3.0-standalone.html</url>
<scope>compile</scope> <distribution>repo</distribution>
</dependency> </license>
<dependency>
<groupId>net.milkbowl.vault</groupId> </licenses>
<artifactId>Vault</artifactId>
<version>1.2.23-SNAPSHOT</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
</dependencies>
<build> <build>
<directory>target</directory> <finalName>${project.name} ${project.version}</finalName>
<outputDirectory>target/classes</outputDirectory>
<finalName>${project.artifactId}</finalName>
<sourceDirectory>src</sourceDirectory> <sourceDirectory>src</sourceDirectory>
<resources> <resources>
<resource> <resource>
<directory>resources</directory> <directory>resources</directory>
<filtering>true</filtering>
</resource> </resource>
</resources> </resources>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>exec-maven-plugin</artifactId>
<groupId>org.codehaus.mojo</groupId>
<version>1.2.1</version>
<executions>
<execution>
<id>Run Test Bukkit Server</id>
<phase>install</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>${basedir}/scripts/test-deployment.sh</executable>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.7.1</version>
<configuration>
<artifactSet>
<includes>
<include>org.mcstats.bukkit:metrics</include>
</includes>
</artifactSet>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build> </build>
<dependencies>
<!--Spigot API-->
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.11-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!--Bukkit API-->
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.11-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<!--Vault-->
<dependency>
<groupId>net.milkbowl.vault</groupId>
<artifactId>Vault</artifactId>
<version>1.6.6</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!--Metrics-->
<dependency>
<groupId>org.mcstats.bukkit</groupId>
<artifactId>metrics</artifactId>
<version>R8-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<repositories> <repositories>
<repository> <repository>
<id>bukkit-repo</id> <id>spigot-repo</id>
<url>http://repo.bukkit.org/content/groups/public</url> <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository> </repository>
<repository> <repository>
<id>vault-repo</id> <id>vault-repo</id>
<url>http://ci.herocraftonline.com/plugin/repository/everything</url> <url>http://nexus.hc.to/content/repositories/pub_releases</url>
</repository> </repository>
<repository>
<id>Plugin Metrics</id>
<url>http://repo.mcstats.org/content/repositories/public</url>
</repository>
</repositories> </repositories>
</project> </project>

11
resources/config.yml Normal file
View File

@ -0,0 +1,11 @@
maxGateBlocks: 50
playerGateBlockUpdateRadius: 64
highlightDuration: 5
saveOnChanges: true
checkForBrokenGateFrames: true
gateTeleportMessage: "Thank you for traveling with Craft Inc. Gates."
showTeleportMessage: true
gateTeleportNoPermissionMessage: "You are not allowed to use this gate!"
showTeleportNoPermissionMessage: true
gateTeleportVehicleNotAllowedMessage: "You must not use that gate while riding!"
gateMaterial: "nether portal"

160
scripts/minecraft.sh Executable file
View File

@ -0,0 +1,160 @@
#!/bin/bash
SCRIPT_DIR=$(dirname "$0")
SERVICE='craftbukkit*.jar'
#USERNAME="minecraft"
CPU_COUNT=2
BUKKIT="$SCRIPT_DIR/../target/lib/$SERVICE"
INVOCATION="java -Xmx1000M -Xms300M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalPacing -XX:ParallelGCThreads=$CPU_COUNT -XX:+AggressiveOpts -jar $BUKKIT nogui"
MCPATH="$SCRIPT_DIR/../bukkit-testserver"
if [ ! -d "$MCPATH" ]; then
mkdir -p "$MCPATH"
fi
ME=$(whoami)
as_user() {
#if [ $ME == $USERNAME ] ; then
bash -c "$1"
#else
#su - $USERNAME -c "$1"
#fi
}
mc_start() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep "craftbukkit" > /dev/null
then
echo "Tried to start but $SERVICE was already running!"
else
echo "$SERVICE was not running... starting."
cd "$MCPATH"
as_user "cd "$MCPATH" && screen -dmS minecraft $INVOCATION"
sleep 7
if ps ax | grep -v grep | grep -v -i SCREEN | grep "craftbukkit" > /dev/null
then
echo "$SERVICE is now running."
else
echo "Could not start $SERVICE."
fi
fi
}
mc_stop() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep "craftbukkit" > /dev/null
then
echo "$SERVICE is running... stopping."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
sleep 2
as_user "screen -p 0 -S minecraft -X eval 'stuff \"stop\"\015'"
sleep 6
else
echo "$SERVICE was not running."
fi
if ps ax | grep -v grep | grep -v -i SCREEN | grep "craftbukkit" > /dev/null
then
echo "$SERVICE could not be shut down... still running."
else
echo "$SERVICE is shut down."
fi
}
mc_save() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep "craftbukkit" > /dev/null
then
echo "$SERVICE is running... saving."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
else
echo "$SERVICE was not running."
fi
}
mc_reload() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep "craftbukkit" > /dev/null
then
echo "$SERVICE is running... reloading."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"reload\"\015'"
else
echo "$SERVICE was not running."
fi
}
mc_reload_or_start() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep "craftbukkit" > /dev/null
then
echo "$SERVICE was already running! Doing a reload now!"
mc_reload
else
echo "$SERVICE was not running... starting."
cd "$MCPATH"
as_user "cd \"$MCPATH\" && screen -dmS minecraft $INVOCATION"
sleep 7
if ps ax | grep -v grep | grep -v -i SCREEN | grep "craftbukkit" > /dev/null
then
echo "$SERVICE is now running."
else
echo "Could not start $SERVICE."
fi
fi
}
mc_ddidderr_admin() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep "craftbukkit" > /dev/null
then
echo "$SERVICE is running... making ddidder to admin and reloading permissions."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"pex user ddidderr group set admin\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"pex reload\"\015'"
else
echo "$SERVICE was not running."
fi
}
case "$1" in
start)
echo "Starting Minecraft..."
mc_start
echo "DONE"
;;
stop)
echo "Stopping Minecraft..."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER SHUTTING DOWN!\"\015'"
mc_stop
echo "DONE"
;;
restart)
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER REBOOT IN 10 SECONDS.\"\015'"
$0 stop
sleep 1
$0 start
;;
reload)
mc_reload
;;
reload_or_start)
echo "Starting or reloading Minecraft..."
mc_reload_or_start
echo "DONE"
;;
ddidderr_admin)
mc_ddidderr_admin
;;
connected)
as_user "screen -p 0 -S minecraft -X eval 'stuff \"who\"\015'"
sleep 2s
tac "$MCPATH"/server.log | grep -m 1 "Connected"
;;
status)
if ps ax | grep -v grep | grep -v -i SCREEN | grep "craftbukkit" > /dev/null
then
echo "$SERVICE is running."
else
echo "$SERVICE is not running."
fi
;;
save)
mc_save
;;
*)
echo "Usage: /etc/init.d/minecraft {start|stop|restart|connected|status}"
exit 1
;;
esac

29
scripts/test-deployment.sh Executable file
View File

@ -0,0 +1,29 @@
#!/bin/bash
SCRIPT_DIR="$(dirname "$0")"
DEVELOPER=$(whoami)
if [ $DEVELOPER = "tobi" ]; then
BUKKIT_DIR="$HOME/minecraft/testbuk"
PLUGIN_DIR="$HOME/minecraft/testbuk/plugins"
START_STOP_SCRIPT="$BUKKIT_DIR/../minecraft.sh"
else
BUKKIT_DIR="$SCRIPT_DIR/../bukkit-testserver"
PLUGIN_DIR="$SCRIPT_DIR/../bukkit-testserver/plugins"
START_STOP_SCRIPT="$SCRIPT_DIR/minecraft.sh"
fi
# TODO: This is a bad solution! Maven should write necessary information into an extra file.
ARTIFACT_ID="$(grep -C5 '<groupId>de.craftinc' "$SCRIPT_DIR/../pom.xml" | grep '<name>' | sed 's/[ \t]*<name>//g' | sed 's/<\/name>[ \t]*//g')"
# TODO: This is a bad solution! Maven should write necessary information into an extra file.
VERSION="$(grep -C5 '<groupId>de.craftinc' "$SCRIPT_DIR/../pom.xml" | grep '<version>' | sed 's/[ \t]*<version>//g' | sed 's/<\/version>[ \t]*//g')"
mkdir -p "$PLUGIN_DIR"
cp "$SCRIPT_DIR/../target/$ARTIFACT_ID $VERSION".jar "$PLUGIN_DIR/"
echo -e "ddidderr\nmice_on_drugs\nMochaccino\nbeuth_el_max" > "$BUKKIT_DIR/ops.txt"
$START_STOP_SCRIPT reload_or_start

View File

@ -1,195 +0,0 @@
package de.craftinc.gates;
import java.util.HashSet;
import java.util.Set;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import de.craftinc.gates.util.FloodUtil;
public abstract class BaseGate
{
/*
* ATTRIBUTES
*/
protected Location location; /* saving both location and gateBlockLocations is redundant but makes it easy to allow players to reshape gates */
protected Set<Location> gateBlockLocations = new HashSet<Location>(); /* Locations of the blocks inside the gate */
protected Location exit;
protected boolean isHidden = false;
protected boolean isOpen = false;
/*
* SETTER & GETTER
*/
public Location getLocation()
{
return location;
}
public void setLocation(Location location) throws Exception
{
this.location = location;
if (isOpen) {
fillGate();
validate();
}
}
public Location getExit()
{
return exit;
}
public void setExit(Location exit) throws Exception
{
this.exit = exit;
validate();
}
public boolean isHidden()
{
return isHidden;
}
public void setHidden(boolean isHidden) throws Exception
{
this.isHidden = isHidden;
if (isHidden == true) {
emptyGate();
}
else if (isOpen()) {
fillGate();
}
validate();
}
public boolean isOpen()
{
return isOpen;
}
public void setOpen(boolean isOpen) throws Exception
{
if (isOpen == true && this.isOpen == false) {
findPortalBlocks();
if (!isHidden) {
fillGate();
}
}
else if (isOpen == false && this.isOpen == true) {
emptyGate();
}
this.isOpen = isOpen;
validate();
}
public Set<Location> getGateBlockLocations()
{
return gateBlockLocations;
}
/*
* GATE BLOCK HANDLING
*/
protected void fillGate()
{
emptyGate();
findPortalBlocks();
// This is not to do an effect
// It is to stop portal blocks from destroying themself as they cant rely on non created blocks :P
for (Location l : gateBlockLocations) {
l.getBlock().setType(Material.GLOWSTONE);
}
for (Location l : gateBlockLocations) {
l.getBlock().setType(Material.PORTAL);
}
}
protected void emptyGate()
{
for (Location l : gateBlockLocations) {
if (l.getBlock().getType() == Material.PORTAL) {
l.getBlock().setType(Material.AIR);
}
}
}
protected void findPortalBlocks()
{
gateBlockLocations = new HashSet<Location>();
Set<Block> gateBlocks = FloodUtil.getGateFrameBlocks(location.getBlock());
if (gateBlocks != null) {
for (Block b : gateBlocks) {
gateBlockLocations.add(b.getLocation());
}
}
}
/*
* VALIDATION
*/
/**
* Checks if valus attributes do add up; will close gate on wrong values.
*/
public void validate() throws Exception
{
if (!isOpen) {
return;
}
if (location == null) {
setOpen(false);
throw new Exception("Gate got closed. It has no location.");
}
if (exit == null) {
setOpen(false);
throw new Exception("Gate got closed. It has no exit.");
}
if (gateBlockLocations.size() == 0) {
setOpen(false);
throw new Exception("Gate got closed. The frame is missing or broken.");
}
if (isHidden == false) {
for (Location l : gateBlockLocations) {
if (l.getBlock().getType() == Material.AIR) {
setOpen(false);
throw new Exception("Gate got closed. The frame is missing or broken.");
}
}
}
}
}

View File

@ -1,212 +0,0 @@
package de.craftinc.gates;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.bukkit.Location;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import de.craftinc.gates.util.LocationUtil;
/**
* Adds persistence and serialization to the base gate class.
*/
public class Gate extends BaseGate implements ConfigurationSerializable
{
/*
* ATTRIBUTES
*/
protected String id;
protected static Map<String, Gate> instances = new HashMap<String, Gate>();
/*
* CONSTRUCTORS
*/
public Gate(String id) throws Exception
{
setId(id);
}
/*
* SETTER & GETTER
*/
public String getId()
{
return id;
}
public void setId(String id) throws Exception
{
if (exists(id)) {
throw new Exception("A gate with '" + id + "' already exists");
}
this.id = id;
}
public String toString()
{
return super.toString() + " " + this.getId();
}
/*
* INTERFACE: ConfigurationSerializable
*/
static protected String idKey = "id";
static protected String locationKey = "location";
static protected String gateBlocksKey = "gateBlocks";
static protected String exitKey = "exit";
static protected String isHiddenKey = "hidden";
static protected String isOpenKey = "open";
static protected String locationYawKey = "locationYaw";
static protected String locationPitchKey = "locationPitch";
static protected String exitYawKey = "exitYaw";
static protected String exitPitchKey = "exitPitch";
@SuppressWarnings("unchecked")
public Gate(Map<String, Object> map)
{
try {
id = map.get(idKey).toString();
isHidden = (Boolean)map.get(isHiddenKey);
isOpen = (Boolean)map.get(isOpenKey);
location = LocationUtil.deserializeLocation((Map<String, Object>) map.get(locationKey));
exit = LocationUtil.deserializeLocation((Map<String, Object>) map.get(exitKey));
if (map.containsKey(exitPitchKey)) {
exit.setPitch(((Double)map.get(exitPitchKey)).floatValue());
exit.setYaw(((Double)map.get(exitYawKey)).floatValue());
}
if (map.containsKey(locationPitchKey)) {
location.setPitch(((Double)map.get(locationPitchKey)).floatValue());
location.setYaw(((Double)map.get(locationYawKey)).floatValue());
}
gateBlockLocations = new HashSet<Location>();
List<Map<String, Object>> serializedGateBlocks = (List<Map<String, Object>>)map.get(gateBlocksKey);
for (Map<String, Object> sgb : serializedGateBlocks) {
gateBlockLocations.add(LocationUtil.deserializeLocation(sgb));
}
}
catch (Exception e) {
Plugin.log("ERROR: Failed to load gate '" + id + "'! (" + e.getMessage() + ")");
Plugin.log("NOTE: This gate will be removed from 'gates.yml' and added to 'invalid_gates.yml'!");
Plugin.instance.storeInvalidGate(map);
return;
}
instances.put(id, this);
}
public Map<String, Object> serialize()
{
try {
validate(); // make sure to not write invalid stuff to disk
}
catch (Exception e) {
Plugin.log("Gate " + this.getId() + " seems to be not valid. It got closed before serializing!");
}
Map<String, Object> retVal = new HashMap<String, Object>();
retVal.put(idKey, id);
retVal.put(locationKey, LocationUtil.serializeLocation(location));
retVal.put(exitKey, LocationUtil.serializeLocation(exit));
retVal.put(isHiddenKey, isHidden);
retVal.put(isOpenKey, isOpen);
if (exit != null) {
retVal.put(exitPitchKey, exit.getPitch());
retVal.put(exitYawKey, exit.getYaw());
}
retVal.put(locationPitchKey, location.getPitch());
retVal.put(locationYawKey, location.getYaw());
List<Map<String, Object>> serializedGateBlocks = new ArrayList<Map<String, Object>>();
for (Location l : gateBlockLocations) {
serializedGateBlocks.add(LocationUtil.serializeLocation(l));
}
retVal.put(gateBlocksKey, serializedGateBlocks);
return retVal;
}
/*
* ENTITY MANAGEMENT
*/
public static Gate get(String id)
{
return instances.get(id);
}
public static boolean exists(String id)
{
return instances.containsKey(id);
}
public static Gate create(String id) throws Exception
{
Gate gate = new Gate(id);
instances.put(gate.id, gate);
return gate;
}
public static void rename(String oldId, String newId) throws Exception
{
Gate gate = get(oldId);
gate.setId(newId);
instances.remove(oldId);
instances.put(gate.id, gate);
}
public static void delete(String id)
{
Gate g = get(id);
if (g != null) {
g.emptyGate();
}
instances.remove(id);
}
public static Collection<Gate> getAll()
{
return instances.values();
}
}

View File

@ -1,290 +1,217 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates; package de.craftinc.gates;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import de.craftinc.gates.controllers.GatesManager;
import de.craftinc.gates.listeners.*;
import de.craftinc.gates.models.Gate;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.ConfigurationUtil;
import net.milkbowl.vault.permission.Permission; import net.milkbowl.vault.permission.Permission;
import org.bukkit.ChatColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.configuration.serialization.ConfigurationSerialization;
import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import de.craftinc.gates.commands.*; import de.craftinc.gates.commands.*;
import de.craftinc.gates.listeners.PluginBlockListener; import org.mcstats.Metrics;
import de.craftinc.gates.listeners.PluginPlayerListener;
import de.craftinc.gates.listeners.PluginPortalListener;
public class Plugin extends JavaPlugin {
private static Plugin instance;
public class Plugin extends JavaPlugin private String baseCommand;
{ protected List<BaseCommand> commands = new ArrayList<>();
public static Plugin instance;
private GatesManager gatesManager = new GatesManager();
public static final String permissionInfo = "craftincgates.info";
public static final String permissionManage = "craftincgates.manage"; private PermissionController permissionController = new PermissionController();
// public static final String permissionAll = "craftincgates.*";
public static final String permissionUse = "craftincgates.use"; private PlayerMoveListener moveListener;
private VehicleMoveListener vehicleListener;
public static Permission permission = null; private PlayerTeleportListener teleportListener = new PlayerTeleportListener();
private PlayerRespawnListener respawnListener = new PlayerRespawnListener();
public PluginPlayerListener playerListener = new PluginPlayerListener(); private PlayerChangedWorldListener worldChangeListener = new PlayerChangedWorldListener();
public PluginBlockListener blockListener = new PluginBlockListener(); private PlayerJoinListener joinListener = new PlayerJoinListener();
public PluginPortalListener portalListener = new PluginPortalListener(); private BlockBreakListener blockBreakListener = new BlockBreakListener();
private File gatesConfigFile; public Plugin() {
private FileConfiguration gatesConfig; instance = this;
moveListener = new PlayerMoveListener(this);
private String baseCommand; vehicleListener = new VehicleMoveListener(this);
}
private String gatesPath = "gates";
public static Plugin getPlugin() {
return instance;
// Commands }
public List<BaseCommand> commands = new ArrayList<BaseCommand>();
public GatesManager getGatesManager() {
return gatesManager;
public Plugin() }
{
instance = this; @Override
} public void onLoad() {
ConfigurationSerialization.registerClass(Gate.class);
}
@Override
public void onLoad() private void setupPermissions() {
{ if (getServer().getPluginManager().getPlugin("Vault") == null) {
ConfigurationSerialization.registerClass(Gate.class); log("Not using setup permission provider provided by Vault.");
}
private void setupPermissions()
{
if (getServer().getPluginManager().getPlugin("Vault") == null) {
return; return;
} }
RegisteredServiceProvider<Permission> rsp = getServer().getServicesManager().getRegistration(Permission.class); RegisteredServiceProvider<Permission> rsp = getServer().getServicesManager().getRegistration(Permission.class);
if (rsp != null)
{
log("Using permission provider provided by Vault.");
permission = rsp.getProvider();
}
else
{
log("Not using setup permission provider provided by Vault.");
}
}
@Override if (rsp != null) {
public void onDisable() log("Using permission provider provided by Vault.");
{ permissionController.setPermission(rsp.getProvider());
// Save gates } else {
saveGates(); log("Not using setup permission provider provided by Vault.");
log("Disabled"); }
} }
@Override
@Override public void onDisable() {
public void onEnable() gatesManager.saveGatesToDisk();
{ log("Disabled");
// Setup permissions }
setupPermissions();
// Add the commands
commands.add(new CommandHelp());
commands.add(new CommandCreate());
commands.add(new CommandDelete());
commands.add(new CommandSetLocation());
commands.add(new CommandSetExit());
commands.add(new CommandOpen());
commands.add(new CommandRename());
commands.add(new CommandClose());
commands.add(new CommandList());
commands.add(new CommandInfo());
commands.add(new CommandSetHidden());
commands.add(new CommandSetVisible());
@Override
// Register events public void onEnable() {
PluginManager pm = this.getServer().getPluginManager(); // Setup Metrics
pm.registerEvents(this.playerListener, this); try {
pm.registerEvents(this.blockListener, this); Metrics metrics = new Metrics(this);
pm.registerEvents(this.portalListener, this); metrics.start();
} catch (IOException e) {
// Load gates log("Failed to start metrics!");
this.gatesConfigFile = new File(getDataFolder(), "gates.yml"); }
if(!this.gatesConfigFile.exists())
{
try {
this.gatesConfigFile.createNewFile();
} catch (IOException e) {
log(Level.SEVERE, "Cannot create gate config file! No gates will be persisted.");
}
}
this.gatesConfig = YamlConfiguration.loadConfiguration(gatesConfigFile);
loadGates();
log("Enabled");
}
// Setup configuration
// -------------------------------------------- // this.saveDefaultConfig();
// Commands
// -------------------------------------------- //
public String getBaseCommand()
{
if (this.baseCommand != null)
return this.baseCommand;
Map<String, Map<String, Object>> Commands = this.getDescription().getCommands();
this.baseCommand = Commands.keySet().iterator().next();
return this.baseCommand;
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args)
{
List<String> parameters = new ArrayList<String>(Arrays.asList(args));
this.handleCommand(sender, parameters);
return true;
}
public void handleCommand(CommandSender sender, List<String> parameters)
{
if (parameters.size() == 0)
{
this.commands.get(0).execute(sender, parameters);
return;
}
String commandName = parameters.get(0).toLowerCase();
parameters.remove(0);
for (BaseCommand fcommand : this.commands)
{
if (fcommand.getAliases().contains(commandName))
{
fcommand.execute(sender, parameters);
return;
}
}
sender.sendMessage("Unknown gate-command \"" + commandName + "\". Try " + "/" + getBaseCommand() + " help");
}
/*
* Logging
*/
public static void log(String msg)
{
log(Level.INFO, msg);
}
public static void log(Level level, String msg) {
Logger.getLogger("Minecraft").log(level, "["+instance.getDescription().getFullName()+"] "+msg);
}
/*
* Saving and Loading Gates
*/
public void loadGates()
{
File gatesFile = new File(getDataFolder(), "gates.yml");
FileConfiguration gatesConfig = YamlConfiguration.loadConfiguration(gatesFile);
gatesConfig.getList(gatesPath); // this will create all the gates
}
public void saveGates()
{
gatesConfig.set(gatesPath, new ArrayList<Object>(Gate.getAll()));
try {
gatesConfig.save(gatesConfigFile);
log("Saved gates to disk.");
}
catch (IOException e) {
log("ERROR: Could not save gates to disk.");
e.printStackTrace();
}
}
public void storeInvalidGate(Map<String, Object> map)
{
File invalidGatesFile = new File(getDataFolder(), "invalid_gates.yml");
Boolean invalidGatesFileExists = invalidGatesFile.exists();
try {
FileWriter fileWriter = new FileWriter(invalidGatesFile, true);
if (!invalidGatesFileExists) {
fileWriter.write("gates:\n");
}
fileWriter.write("- ==: ");
fileWriter.write(map.get("==").toString() + "\n");
map.remove("==");
fileWriter.write("\topen: false\n");
map.remove("open");
fileWriter.write("\tgateBlocks: []\n");
map.remove("gateBlocks");
for (String key : map.keySet()) {
Object value = map.get(key);
fileWriter.write("\t" + key + ": ");
if (value instanceof Map) {
fileWriter.write("\n");
@SuppressWarnings("unchecked")
Map<String, Object> valueMap = (Map<String, Object>)value;
for (String k : valueMap.keySet()) {
Object v = valueMap.get(k);
fileWriter.write("\t\t" + k + ": " + v.toString() + "\n");
}
} // Setup permissions
else { setupPermissions();
fileWriter.write(value.toString() + "\n");
} // Add the commands
commands.add(new CommandHelp());
} commands.add(new CommandNew());
commands.add(new CommandRemove());
fileWriter.close(); commands.add(new CommandLocation());
} commands.add(new CommandExit());
catch (IOException e) { commands.add(new CommandTriggerOpen());
log("ERROR: Could not save invalid gates to disk."); commands.add(new CommandRename());
e.printStackTrace(); commands.add(new CommandList());
} commands.add(new CommandInfo());
} commands.add(new CommandNearby());
commands.add(new CommandTriggerVehicles());
commands.add(new CommandMaterial());
commands.add(new CommandTeleport());
// Register events
this.registerEventListeners();
// Load gates
boolean success = gatesManager.loadGatesFromDisk();
if (success) {
log("Enabled");
} else {
PluginManager pm = this.getServer().getPluginManager();
pm.disablePlugin(this);
}
}
public PermissionController getPermissionController() {
return permissionController;
}
private void registerEventListeners() {
PluginManager pm = this.getServer().getPluginManager();
pm.registerEvents(this.moveListener, this);
pm.registerEvents(this.teleportListener, this);
pm.registerEvents(this.respawnListener, this);
pm.registerEvents(this.worldChangeListener, this);
pm.registerEvents(this.joinListener, this);
pm.registerEvents(this.vehicleListener, this);
if (getConfig().getBoolean(ConfigurationUtil.confCheckForBrokenGateFramesKey)) {
pm.registerEvents(this.blockBreakListener, this);
}
}
// -------------------------------------------- //
// Commands
// -------------------------------------------- //
public String getBaseCommand() {
if (this.baseCommand != null)
return this.baseCommand;
Map<String, Map<String, Object>> Commands = this.getDescription().getCommands();
this.baseCommand = Commands.keySet().iterator().next();
return this.baseCommand;
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
List<String> parameters = new ArrayList<>(Arrays.asList(args));
this.handleCommand(sender, parameters);
return true;
}
private void handleCommand(CommandSender sender, List<String> parameters) {
if (parameters.size() == 0) {
this.commands.get(0).execute(sender, parameters);
return;
}
String commandName = parameters.get(0).toLowerCase();
parameters.remove(0);
for (BaseCommand command : this.commands) {
if (command.getAliases().contains(commandName)) {
command.execute(sender, parameters);
return;
}
}
sender.sendMessage(ChatColor.RED + "Unknown gate-command \"" + commandName + "\"." +
ChatColor.GREEN + " Try " + "/" + getBaseCommand() + " help");
}
/*
* Logging
*/
public static void log(String msg) {
log(Level.INFO, msg);
}
public static void log(Level level, String msg) {
Logger.getLogger("Minecraft").log(level, "[" + instance.getDescription().getFullName() + "] " + msg);
}
} }

View File

@ -1,273 +1,192 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.ConfigurationUtil;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import de.craftinc.gates.Gate; import de.craftinc.gates.models.Gate;
import de.craftinc.gates.controllers.GatesManager;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.TextUtil; import de.craftinc.gates.util.TextUtil;
public abstract class BaseCommand public abstract class BaseCommand {
{ PermissionController permissionController;
protected List<String> aliases = new ArrayList<String>(); GatesManager gatesManager;
protected List<String> requiredParameters = new ArrayList<String>();
protected List<String> optionalParameters = new ArrayList<String>();
protected String helpDescription = "no description";
protected List<String> parameters;
protected CommandSender sender;
protected Player player;
protected Gate gate;
protected boolean senderMustBePlayer = true;
protected boolean hasGateParam = true;
protected String requiredPermission;
protected boolean needsPermissionAtCurrentLocation;
protected boolean shouldPersistToDisk;
List<String> aliases = new ArrayList<>();
public List<String> getAliases() { List<String> requiredParameters = new ArrayList<>();
return aliases; List<String> optionalParameters = new ArrayList<>();
}
public void execute(CommandSender sender, List<String> parameters) {
this.sender = sender;
this.parameters = parameters;
if (!this.validateCall()) {
return;
}
if (this.senderMustBePlayer) {
this.player = (Player)sender;
}
this.perform();
if (this.shouldPersistToDisk) {
Plugin.instance.saveGates();
}
}
abstract protected void perform();
protected void sendMessage(String message) {
sender.sendMessage(message);
}
protected void sendMessage(List<String> messages) {
for(String message : messages) {
this.sendMessage(message);
}
}
protected boolean validateCall()
{
boolean allParamtertersThere = parameters.size() >= requiredParameters.size();
boolean senderIsPlayer = this.sender instanceof Player;
boolean hasGateParameter = false;
if (this.hasGateParam == true && this.parameters.size() > 0 && this.setGateUsingParameter(this.parameters.get(0))) {
hasGateParameter = true;
}
boolean senderHasPermission = this.hasPermission();
boolean valid = false; String helpDescription = "no description";
if (this.senderMustBePlayer && !senderIsPlayer)
{
sendMessage(ChatColor.RED + "This command can only be used by ingame players.");
valid = false;
}
else if (!allParamtertersThere)
{
sendMessage(ChatColor.RED + "Some parameters are missing! " + ChatColor.AQUA + "Usage: " + this.getUseageTemplate(true));
valid = false;
}
else if (!senderHasPermission && this.hasGateParam)
{
sendMessage(ChatColor.RED + "You either provided a invalid gate or do not have permission to " + this.helpDescription.toLowerCase());
valid = false;
}
else if (!senderHasPermission)
{
sendMessage(ChatColor.RED + "You lack the permissions to " + this.helpDescription.toLowerCase());
valid = false;
}
else if (this.hasGateParam && !hasGateParameter)
{
sendMessage(ChatColor.RED + "There exists no gate with id " + this.parameters.get(0));
valid = false;
}
else
{
valid = true;
}
return valid;
}
protected boolean setGateUsingParameter(String param)
{
if (!Gate.exists(param))
{
return false;
}
else
{
gate = Gate.get(param);
return true;
}
}
/**
* This will return false if a gate is required for this command but this.gate == null.
*/
protected boolean hasPermission()
{
if (Plugin.permission == null) // fallback Ð use the standard bukkit permission system
{
return this.sender.hasPermission(this.requiredPermission);
}
Player p = null;
if (this.sender instanceof Player)
{
p = (Player) this.sender;
}
else
{
// sender is no player Ð there is no information about the senders locations
return Plugin.permission.has(this.sender, this.requiredPermission);
}
boolean hasPermission = false;
if (this.requiredPermission.equals(Plugin.permissionInfo))
{
if (this.hasGateParam)
{
hasPermission = this.hasPermissionAtGateLocationAndExit(p);
}
else
{
hasPermission = Plugin.permission.has(p.getWorld(), p.getName(), this.requiredPermission);
}
}
else if (this.requiredPermission.equals(Plugin.permissionUse) )
{
hasPermission = this.hasPermissionAtGateLocationAndExit(p);
}
else if (this.requiredPermission.equals(Plugin.permissionManage))
{
if (this.needsPermissionAtCurrentLocation && this.hasGateParam)
{
boolean hasPersmissionAtCurrentLocation = Plugin.permission.has(p.getWorld(), p.getName(), this.requiredPermission);
hasPermission = hasPersmissionAtCurrentLocation && this.hasPermissionAtGateLocationAndExit(p);
}
else if (this.needsPermissionAtCurrentLocation)
{
hasPermission = Plugin.permission.has(p.getWorld(), p.getName(), this.requiredPermission);
}
else
{
hasPermission = this.hasPermissionAtGateLocationAndExit(p);
}
}
return hasPermission;
}
protected boolean hasPermissionAtGateLocationAndExit(Player p)
{
if (this.gate == null || p == null) // make sure we don't run into a nullpointer exception
{
return false;
}
boolean permAtLocation = Plugin.permission.has(this.gate.getLocation().getWorld(), p.getName(), this.requiredPermission); List<String> parameters;
CommandSender sender;
boolean permAtExit; Player player;
Gate gate;
if (this.gate.getExit() == null)
{
permAtExit = true;
}
else
{
permAtExit = Plugin.permission.has(this.gate.getExit().getWorld(), p.getName(), this.requiredPermission);
}
return permAtLocation & permAtExit; boolean senderMustBePlayer = true;
} boolean hasGateParam = true;
String requiredPermission;
// -------------------------------------------- // boolean needsPermissionAtCurrentLocation;
// Help and usage description
// -------------------------------------------- // boolean shouldPersistToDisk;
protected String getUsageTemplate(boolean withColor, boolean withDescription) {
String ret = ""; public List<String> getAliases() {
return aliases;
if (withColor) { }
ret += ChatColor.AQUA;
} public BaseCommand() {
gatesManager = Plugin.getPlugin().getGatesManager();
ret += "/" + Plugin.instance.getBaseCommand() + " " + TextUtil.implode(this.getAliases(), ",")+" "; permissionController = Plugin.getPlugin().getPermissionController();
}
List<String> parts = new ArrayList<String>();
public void execute(CommandSender sender, List<String> parameters) {
for (String requiredParameter : this.requiredParameters) { this.sender = sender;
parts.add("["+requiredParameter+"]"); this.parameters = parameters;
}
if (!this.validateCall()) {
for (String optionalParameter : this.optionalParameters) { return;
parts.add("*["+optionalParameter+"]"); }
}
if (sender instanceof Player) {
if (withColor) { this.player = (Player)sender;
ret += ChatColor.DARK_AQUA; }
}
this.perform();
ret += TextUtil.implode(parts, " ");
if (this.shouldPersistToDisk && getSaveOnChanges()) {
if (withDescription) { gatesManager.saveGatesToDisk();
ret += " "; }
}
if (withColor) {
ret += ChatColor.YELLOW; abstract protected void perform();
}
void sendMessage(String message) {
ret += this.helpDescription; sender.sendMessage(message);
} }
return ret;
} void sendMessage(List<String> messages) {
for (String message : messages) {
protected String getUseageTemplate(boolean withColor) { this.sendMessage(message);
return getUsageTemplate(withColor, false); }
} }
protected String getUseageTemplate() { boolean setGateUsingParameter(String param) {
return getUseageTemplate(true); if (!gatesManager.gateExists(param)) {
} return false;
} else {
gate = gatesManager.getGateWithId(param);
return true;
}
}
/**
* This will return false if a gate is required for this command but this.gate == null.
*/
boolean hasPermission() {
if (needsPermissionAtCurrentLocation) {
return permissionController.hasPermission(sender, requiredPermission);
} else {
return permissionController.hasPermission(sender, gate, requiredPermission);
}
}
/*
Help and usage description
*/
String getUsageTemplate(boolean withDescription) {
String ret = "";
ret += ChatColor.AQUA;
ret += "/" + Plugin.getPlugin().getBaseCommand() + " " + TextUtil.implode(getAliases(), ",") + " ";
List<String> parts = new ArrayList<>();
for (String requiredParameter : requiredParameters) {
parts.add("[" + requiredParameter + "]");
}
for (String optionalParameter : optionalParameters) {
parts.add("*[" + optionalParameter + "]");
}
ret += ChatColor.DARK_AQUA;
ret += TextUtil.implode(parts, " ");
if (withDescription) {
ret += " ";
ret += ChatColor.YELLOW;
ret += helpDescription;
}
return ret;
}
private boolean validateCall() {
boolean allParametersThere = parameters.size() >= requiredParameters.size();
boolean senderIsPlayer = this.sender instanceof Player;
boolean hasGateParameter = false;
if (this.hasGateParam && this.parameters.size() > 0 && this.setGateUsingParameter(this.parameters.get(0))) {
hasGateParameter = true;
}
boolean senderHasPermission = this.hasPermission();
boolean valid;
if (this.senderMustBePlayer && !senderIsPlayer) {
sendMessage(ChatColor.RED + "This command can only be used by in-game players.");
valid = false;
} else {
if (!allParametersThere) {
sendMessage(ChatColor.RED + "Some parameters are missing! " +
ChatColor.AQUA + "Usage: " +
getUsageTemplate(false)
);
valid = false;
} else if ((!senderHasPermission && this.hasGateParam) ||
(!senderHasPermission) ||
(this.hasGateParam && !hasGateParameter)) {
sendMessage(ChatColor.RED +
"You either provided a invalid gate or do not have permission to " +
this.helpDescription.toLowerCase()
);
valid = false;
} else {
valid = true;
}
}
return valid;
}
private boolean getSaveOnChanges() {
FileConfiguration config = Plugin.getPlugin().getConfig();
return config.getBoolean(ConfigurationUtil.confSaveOnChangesKey);
}
} }

View File

@ -1,3 +1,19 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import org.bukkit.Location; import org.bukkit.Location;
@ -5,27 +21,21 @@ import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
public abstract class BaseLocationCommand extends BaseCommand abstract class BaseLocationCommand extends BaseCommand {
{
protected Location getValidPlayerLocation() Location getValidPlayerLocation() {
{ // The player might stand in a half block or a sign or whatever
// The player might stand in a halfblock or a sign or whatever // Therefore we load some extra locations and blocks
// Therefore we load som extra locations and blocks Location location = player.getLocation().clone();
Block playerBlock = player.getLocation().getBlock(); Block playerBlock = location.getBlock();
Block upBlock = playerBlock.getRelative(BlockFace.UP); Block upBlock = playerBlock.getRelative(BlockFace.UP);
if (playerBlock.getType() == Material.AIR) { if (playerBlock.getType() == Material.AIR) {
return player.getLocation(); return location;
} } else if (upBlock.getType() == Material.AIR) {
else if (upBlock.getType() == Material.AIR) { return location.add(0, 1, 0);
return new Location(player.getLocation().getWorld(), } else {
player.getLocation().getX(), return null;
player.getLocation().getY() + 1, }
player.getLocation().getZ(), }
player.getLocation().getYaw(),
player.getLocation().getPitch());
}
return null;
}
} }

View File

@ -1,48 +0,0 @@
package de.craftinc.gates.commands;
import java.util.logging.Level;
import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin;
public class CommandClose extends BaseCommand
{
public CommandClose()
{
aliases.add("close");
aliases.add("c");
requiredParameters.add("id");
helpDescription = "Closes a gate to prevent players from using it.";
requiredPermission = Plugin.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
senderMustBePlayer = false;
}
@Override
public void perform()
{
try
{
gate.setOpen(false);
sendMessage(ChatColor.GREEN + "The gate was closed.");
}
catch(Exception e)
{
sendMessage(ChatColor.RED + "Opening the gate failed! See server log for more information");
Plugin.log(Level.WARNING, e.getMessage());
e.printStackTrace();
}
}
}

View File

@ -1,72 +0,0 @@
package de.craftinc.gates.commands;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import de.craftinc.gates.Gate;
import de.craftinc.gates.Plugin;
public class CommandCreate extends BaseLocationCommand
{
public CommandCreate()
{
aliases.add("create");
aliases.add("new");
requiredParameters.add("id");
senderMustBePlayer = true;
hasGateParam = false;
helpDescription = "Create a gate at your current location.";
requiredPermission = Plugin.permissionManage;
needsPermissionAtCurrentLocation = true;
shouldPersistToDisk = true;
senderMustBePlayer = true;
}
public void perform()
{
String id = parameters.get(0);
try
{
gate = Gate.create(id);
sendMessage(ChatColor.GREEN + "Gate with id '" + id + "' was created.");
}
catch (Exception e)
{
sendMessage(ChatColor.RED + "Creating the gate failed!" + e.getMessage() + "See server log for more information");
return;
}
Location playerLocation = getValidPlayerLocation();
if (playerLocation != null)
{
try
{
gate.setLocation(playerLocation);
sendMessage(ChatColor.AQUA + "The gates location has been set to your current location.");
}
catch (Exception e)
{
}
}
else
{
sendMessage(ChatColor.GREEN + "Gate with id \"" + id + "\" was created.");
sendMessage("Now you should build a frame and:");
sendMessage(new CommandSetLocation().getUsageTemplate(true, true));
}
}
}

View File

@ -1,38 +0,0 @@
package de.craftinc.gates.commands;
import org.bukkit.ChatColor;
import de.craftinc.gates.Gate;
import de.craftinc.gates.Plugin;
public class CommandDelete extends BaseCommand
{
public CommandDelete()
{
aliases.add("delete");
aliases.add("del");
aliases.add("remove");
aliases.add("rm");
requiredParameters.add("id");
senderMustBePlayer = false;
helpDescription = "Removes the gate from the game.";
requiredPermission = Plugin.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
senderMustBePlayer = false;
}
public void perform()
{
Gate.delete(gate.getId());
sendMessage(ChatColor.GREEN + "Gate with id '" + gate.getId() + "' was deleted.");
}
}

View File

@ -0,0 +1,54 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.commands;
import java.util.logging.Level;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin;
import org.bukkit.Location;
public class CommandExit extends BaseCommand {
public CommandExit() {
aliases.add("exit");
aliases.add("e");
requiredParameters.add("id");
helpDescription = "Change exit of location.";
requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = true;
shouldPersistToDisk = true;
senderMustBePlayer = true;
}
public void perform() {
try {
Location oldExit = gate.getExit();
gate.setExit(player.getLocation());
sendMessage(ChatColor.GREEN + "The exit of gate '" + gate.getId() + "' is now where you stand.");
gatesManager.handleGateExitChange(gate, oldExit);
} catch (Exception e) {
GateBlockChangeSender.updateGateBlocks(gate);
sendMessage(ChatColor.RED + "Setting the exit for the gate failed! See server log for more information");
Plugin.log(Level.WARNING, e.getMessage());
e.printStackTrace();
}
}
}

View File

@ -1,104 +1,68 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import java.util.ArrayList; import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.TextUtil;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.bukkit.command.CommandSender; public class CommandHelp extends BaseCommand {
import de.craftinc.gates.Gate; private static List<String> help;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.TextUtil;
public class CommandHelp extends BaseCommand public CommandHelp() {
{ aliases.add("help");
public static List<List<String>> helpPages; aliases.add("?");
helpDescription = "prints this help page";
static requiredPermission = PermissionController.permissionInfo;
{ hasGateParam = false;
// sort the usage strings needsPermissionAtCurrentLocation = false;
List<String> allUsageStrings = new ArrayList<String>(); shouldPersistToDisk = false;
senderMustBePlayer = false;
allUsageStrings.add( new CommandHelp().getUsageTemplate(true, true) ); }
allUsageStrings.add( new CommandCreate().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandDelete().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandSetLocation().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandSetExit().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandOpen().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandRename().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandClose().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandList().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandInfo().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandSetHidden().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandSetVisible().getUsageTemplate(true, true) );
Collections.sort(allUsageStrings);
// put 5 commands on one page
helpPages = new ArrayList<List<String>>();
while (!allUsageStrings.isEmpty())
{
int toIndex = allUsageStrings.size() >= 6 ? 5 : allUsageStrings.size();
List<String> currentHelpPage = new ArrayList<String>(allUsageStrings.subList(0, toIndex));
helpPages.add(currentHelpPage);
allUsageStrings.removeAll(currentHelpPage);
}
}
public CommandHelp()
{
aliases.add("help");
aliases.add("h");
aliases.add("?");
optionalParameters.add("page");
helpDescription = "prints this help page";
requiredPermission = Plugin.permissionInfo;
hasGateParam = false;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = false;
senderMustBePlayer = false;
}
public boolean hasPermission(CommandSender sender, Gate gate) public void perform() {
{ sendMessage(TextUtil.titleSize("Craft Inc. Gates Help"));
return true; sendMessage(getHelp());
} }
private List<String> getHelp() {
public void perform() if (help == null) {
{ help = Arrays.asList(
int page = 1; new CommandHelp().getUsageTemplate(true),
new CommandNew().getUsageTemplate(true),
if (parameters.size() > 0) new CommandRemove().getUsageTemplate(true),
{ new CommandLocation().getUsageTemplate(true),
try new CommandExit().getUsageTemplate(true),
{ new CommandTriggerOpen().getUsageTemplate(true),
page = Integer.parseInt(parameters.get(0)); new CommandRename().getUsageTemplate(true),
} new CommandList().getUsageTemplate(true),
catch (NumberFormatException e) new CommandInfo().getUsageTemplate(true),
{ new CommandNearby().getUsageTemplate(true),
// wasn't an integer new CommandTriggerVehicles().getUsageTemplate(true),
} new CommandTeleport().getUsageTemplate(true),
} new CommandMaterial().getUsageTemplate(true)
);
sendMessage(TextUtil.titleize("Craft Inc. Gates Help (" + page + "/" + helpPages.size() + ")")); Collections.sort(help);
}
page -= 1;
if (page < 0 || page >= helpPages.size()) return help;
{ }
sendMessage("This page does not exist");
return;
}
sendMessage(helpPages.get(page));
}
} }

View File

@ -1,60 +1,113 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.models.Gate;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.TextUtil; import de.craftinc.gates.util.TextUtil;
import org.bukkit.entity.Player;
import java.util.HashSet;
public class CommandInfo extends BaseCommand {
public CommandInfo() {
aliases.add("info");
aliases.add("i");
optionalParameters.add("id");
helpDescription = "Print detailed information about a certain or the closest gate.";
requiredPermission = PermissionController.permissionInfo;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = false;
senderMustBePlayer = false;
hasGateParam = false;
}
public void perform() {
if (this.parameters.size() > 0) {
if (!this.setGateUsingParameter(this.parameters.get(0))) {
sendMessage(ChatColor.RED + "You either provided a invalid gate or do not have permission to " + this.helpDescription.toLowerCase());
return;
}
sendMessage(TextUtil.titleSize("Information about: '" + ChatColor.WHITE + gate.getId() + ChatColor.YELLOW + "'"));
} else {
boolean senderIsPlayer = this.sender instanceof Player;
if (!senderIsPlayer) {
sendMessage(ChatColor.RED + "Only ingame players can perform this command without a supplied gate id!");
return;
}
Player p = (Player) this.sender;
this.gate = gatesManager.getNearestGate(p.getLocation());
if (!this.hasPermission() || this.gate == null) {
sendMessage(ChatColor.RED + "There is either no gate nearby or you do not have permission to " + this.helpDescription.toLowerCase());
return;
}
Plugin.log(this.gate.toString());
sendMessage(TextUtil.titleSize("Information about closest gate: '" + ChatColor.WHITE + gate.getId() + ChatColor.YELLOW + "'"));
}
String openMessage = ChatColor.DARK_AQUA + "This gate is";
if (gate.isOpen())
openMessage += ChatColor.AQUA + " open";
else
openMessage += ChatColor.AQUA + " closed";
openMessage += ".\n";
sendMessage(openMessage);
if (gate.getLocation() != null)
sendMessage(ChatColor.DARK_AQUA + "location: " + ChatColor.AQUA + "( " + (int) gate.getLocation().getX() +
" | " + (int) gate.getLocation().getY() + " | " + (int) gate.getLocation().getZ() + " ) in " +
gate.getLocation().getWorld().getName());
else
sendMessage(ChatColor.DARK_AQUA + "NOTE: this gate has no location");
if (gate.getExit() != null)
sendMessage(ChatColor.DARK_AQUA + "exit: " + ChatColor.AQUA + "( " + (int) gate.getExit().getX() + " | "
+ (int) gate.getExit().getY() + " | " + (int) gate.getExit().getZ() + " ) in " +
gate.getExit().getWorld().getName());
else
sendMessage(ChatColor.DARK_AQUA + "NOTE: this gate has no exit");
public class CommandInfo extends BaseCommand if (gate.getAllowsVehicles())
{ sendMessage(ChatColor.DARK_AQUA + "You can ride through this gate.");
public CommandInfo()
{
aliases.add("info");
aliases.add("details");
aliases.add("i");
aliases.add("d");
requiredParameters.add("id");
helpDescription = "Prints detailed informations about a certain gate.";
requiredPermission = Plugin.permissionInfo;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = false;
senderMustBePlayer = false;
}
public void perform()
{
sendMessage(TextUtil.titleize("Information about: '" + ChatColor.WHITE + gate.getId() + ChatColor.YELLOW + "'"));
String openHiddenMessage = ChatColor.DARK_AQUA + "This gate is";
if (gate.isOpen())
openHiddenMessage += ChatColor.AQUA + " open";
else
openHiddenMessage += ChatColor.AQUA + " closed";
if (gate.isHidden())
openHiddenMessage += ChatColor.DARK_AQUA +" and" + ChatColor.AQUA + " hidden";
openHiddenMessage += ".\n";
sendMessage(openHiddenMessage);
if (gate.getLocation() != null)
sendMessage(ChatColor.DARK_AQUA + "from: " + ChatColor.AQUA + "( " + gate.getLocation().getBlockX() + " | " + gate.getLocation().getBlockY() + " | " + gate.getLocation().getBlockZ() + " ) in " + gate.getLocation().getWorld().getName());
else
sendMessage(ChatColor.DARK_AQUA + "NOTE: this gate has no 'from' location");
if (gate.getExit() != null)
sendMessage(ChatColor.DARK_AQUA + "to: " + ChatColor.AQUA + "( " + gate.getExit().getBlockX() + " | " + gate.getExit().getBlockY() + " | " + gate.getExit().getBlockZ() + " ) in " + gate.getExit().getWorld().getName());
else
sendMessage(ChatColor.DARK_AQUA + "NOTE: this gate has no 'to' location");
}
sendMessage(ChatColor.DARK_AQUA + "This gate is made of "
+ ChatColor.AQUA + gate.getMaterial() + ChatColor.DARK_AQUA + ".");
if (this.sender instanceof Player) {
HashSet<Gate> set = new HashSet<>();
set.add(this.gate);
GateBlockChangeSender.temporaryHighlightGatesFrames((Player)this.sender, set);
}
}
} }

View File

@ -1,3 +1,19 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import java.util.ArrayList; import java.util.ArrayList;
@ -5,245 +21,276 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import de.craftinc.gates.controllers.PermissionController;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
import de.craftinc.gates.Gate; import de.craftinc.gates.models.Gate;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.TextUtil; import de.craftinc.gates.util.TextUtil;
public class CommandList extends BaseCommand {
public class CommandList extends BaseCommand private static final int linesPerPage = 15;
{
public CommandList()
{
aliases.add("list");
aliases.add("ls");
optionalParameters.add("page");
hasGateParam = false;
needsPermissionAtCurrentLocation = false;
helpDescription = "lists all availible gates.";
requiredPermission = Plugin.permissionInfo;
shouldPersistToDisk = false;
senderMustBePlayer = false;
}
protected String intToTitleString(int i)
{
if ( i < 26 ) {
return ChatColor.DARK_AQUA + "" + (char)(i+65) + ":";
}
else if ( i == 26 ) {
return ChatColor.DARK_AQUA + "0 - 9:";
}
else {
return ChatColor.DARK_AQUA + "!@#$:";
}
}
/**
* Method for returning a collection of gates the player is allowed to see.
*/
protected Collection<Gate> getAllGates()
{
Collection<Gate> gates = Gate.getAll();
if (this.sender instanceof Player && Plugin.permission != null)
{
Player p = (Player)this.sender;
Collection<Gate> gatesCopy = new ArrayList<Gate>(gates); // create a copy since we cannot iterate over a collection while modifying it!
for (Gate gate : gatesCopy) {
if (!Plugin.permission.has(gate.getLocation().getWorld(), p.getName(), this.requiredPermission))
{
gates.remove(gate);
}
else if (gate.getExit() != null && !Plugin.permission.has(gate.getExit().getWorld(), p.getName(), this.requiredPermission))
{
gates.remove(gate);
}
}
}
return gates;
}
// pages start at 1
// will return null if requested page not availible
protected List<String> message(int page)
{
Collection<Gate> gates = this.getAllGates();
if (gates.size() == 0) {
return null;
}
/* sort all gates by there first character
* put gates in corresponding Lists
* list 0-25: a,b,c, ... ,z
* list 26: 0-9
* list 27: other
*/
List<List<String>> ids = new ArrayList<List<String>>();
for (int i=0; i<28; i++) {
ids.add(new ArrayList<String>());
}
for (Gate gate : gates) {
String id = gate.getId();
int first = id.charAt(0);
if (first > 96 && first < 123) { // convert lower case chars
first -= 97;
}
else if (first > 64 && first < 91) { // convert upper case chars
first -= 65;
}
else if (first > 47 && first < 58) { // convert numbers
first = 26;
}
else { // everything else
first = 27;
}
ids.get(first).add(id);
}
/* calculating which gates will be displayed on which page.
* this is a little bit fuzzy. but hopefully it will look
* great. (tell me if there is a better way!)
*/
int currentPage = 1;
int currentStartingCharList = 0;
boolean finishedCurrentIds = true;
List<String> pageMessages = new ArrayList<String>();
while (currentStartingCharList < ids.size()) {
int linesLeftOnCurrentPage = 9;
while (linesLeftOnCurrentPage > 1 && currentStartingCharList < ids.size()) {
List<String> currentIds = ids.get(currentStartingCharList);
if (currentIds.size() > 0) {
// add header line
if (currentPage == page) {
pageMessages.add(intToTitleString(currentStartingCharList));
}
//sort
Collections.sort(currentIds);
// add ids
int numLinesForCurrentChar = TextUtil.implode(currentIds, ", ").length() / 52 + 2;
if (numLinesForCurrentChar <= linesLeftOnCurrentPage) { // all ids fit on current page
linesLeftOnCurrentPage -= numLinesForCurrentChar;
if (currentPage == page) {
pageMessages.add(ChatColor.AQUA + TextUtil.implode(currentIds, ", "));
if (finishedCurrentIds == false) {
pageMessages.set(pageMessages.size() -2, pageMessages.get(pageMessages.size() -2) + " (more on previous page)");
}
}
finishedCurrentIds = true;
}
else { // NOT all ids fit on current page
int charsAvailible = (linesLeftOnCurrentPage - 1) * 52;
int idsPos = 0;
do {
charsAvailible -= currentIds.get(idsPos).length() + 2;
idsPos++;
} while (charsAvailible > 0);
List<String> idsToPutOnCurrentPage = currentIds.subList(0, idsPos);
currentIds.remove(idsToPutOnCurrentPage);
String stringToPutOnCurrentPage = TextUtil.implode(idsToPutOnCurrentPage, ", ");
if (currentPage == page) {
pageMessages.add(ChatColor.AQUA + stringToPutOnCurrentPage);
pageMessages.set(pageMessages.size() -2, pageMessages.get(pageMessages.size() -2) + " (more on next page)");
}
linesLeftOnCurrentPage -= stringToPutOnCurrentPage.length() / 52 + 2;
finishedCurrentIds = false;
}
}
if (finishedCurrentIds) {
currentStartingCharList++;
}
}
currentPage++;
}
if (pageMessages.isEmpty())
{
return null;
}
else {
ArrayList<String> retVal = new ArrayList<String>();
retVal.add(TextUtil.titleize("List of all gates (" + page + "/" + --currentPage + ")"));
retVal.addAll(pageMessages);
return retVal;
}
}
protected int getPageParameter()
{
int page = 1;
try {
page = new Integer(parameters.get(0));
}
catch (Exception e) { }
return page;
}
public void perform()
{
int page = this.getPageParameter();
List<String> messages = message(page);
if (messages == null)
{
if (page == 1) // no gates exist
{
sendMessage(ChatColor.RED + "There are no gates yet. " + ChatColor.RESET +
"(Note that you might not be allowed to get information about certain gates)");
}
else // the requested page does not exist
{
sendMessage(ChatColor.RED + "The requested page is not availible");
}
} /* this is actually not true. the font used by Minecraft is not
else monospaced. but there seems to be no (easy) way to calculate
{ the drawing-size of a string.
sendMessage(messages); */
} private static final int charactersPerLine = 52;
}
public CommandList() {
aliases.add("list");
aliases.add("ls");
optionalParameters.add("page");
hasGateParam = false;
needsPermissionAtCurrentLocation = false;
helpDescription = "lists all availible gates.";
requiredPermission = PermissionController.permissionInfo;
shouldPersistToDisk = false;
senderMustBePlayer = false;
}
public void perform() {
int page = this.getPageParameter();
List<String> allPages = this.pagedGateIds();
if (allPages == null) { // no gates exist
sendMessage(ChatColor.RED + "There are no gates yet. " + ChatColor.RESET +
"(Note that you might not be allowed to get information about certain gates)");
return;
}
if (page > allPages.size() || page < 1) {
sendMessage(ChatColor.RED + "The requested page is not available");
return;
}
String message = TextUtil.titleSize("List of all gates (" + page + "/" + allPages.size() + ")") + "\n";
message += allPages.get(page - 1);
sendMessage(message);
}
private static List<String> linesOfGateIds(List<String> gates) {
List<String> lines = new ArrayList<>();
int index = 0;
List<String> gateIdsForCurrentLine = new ArrayList<>();
int numCharactersInCurrentLine = 0;
while (index < gates.size()) {
String gateId = gates.get(index);
int gateIdLength = gateId.length() + 2; // actual length + comma + whitespace
if (gateIdLength > charactersPerLine && numCharactersInCurrentLine == 0) { // special case: very long gate id
gateIdsForCurrentLine = new ArrayList<>();
numCharactersInCurrentLine = 0;
while ((gateId.length() + 2) > charactersPerLine) {
int cutPos = charactersPerLine;
// is the id too long to add comma and whitespace but not longer than the line?
if (gateId.length() <= charactersPerLine) {
cutPos -= 2;
}
lines.add(gateId.substring(0, cutPos));
gateId = gateId.substring(cutPos, gateId.length());
}
gateIdsForCurrentLine.add(gateId);
numCharactersInCurrentLine += gateId.length();
index++;
} else if ((numCharactersInCurrentLine + gateIdLength) <= charactersPerLine) { // gate fits into current line
gateIdsForCurrentLine.add(gateId);
numCharactersInCurrentLine += gateIdLength;
index++;
} else { // the current gate does not fit on the
lines.add(TextUtil.implode(gateIdsForCurrentLine, ", ") + ", ");
gateIdsForCurrentLine = new ArrayList<>();
numCharactersInCurrentLine = 0;
}
}
lines.add(TextUtil.implode(gateIdsForCurrentLine, ", "));
return lines;
}
private static String intToTitleString(int i, boolean addPreviousPageNote, boolean addNextPageNote) {
String retVal = ChatColor.DARK_AQUA + "";
if (i < 26) {
retVal += (char) (i + 65);
} else if (i == 26) {
retVal += "0-9";
} else {
retVal += "!@#$";
}
if (addPreviousPageNote && addNextPageNote) {
retVal += " (more on previous and next page)";
} else if (addPreviousPageNote) {
retVal += " (more on previous page)";
} else if (addNextPageNote) {
retVal += " (more on next page)";
}
return retVal + "\n";
}
/**
* Method for getting a collection of gates the player is allowed to see.
*/
private Collection<Gate> getAllGates() {
Collection<Gate> gates = gatesManager.allGates();
// create a copy since we cannot iterate over a collection while modifying it!
Collection<Gate> gatesCopy = new ArrayList<>(gates);
for (Gate gate : gatesCopy) {
if (!this.permissionController.hasPermission(this.sender, gate, this.requiredPermission)) {
gates.remove(gate);
}
}
return gates;
}
/**
* Sorts all gates by there first character.
* Puts gates in corresponding Lists: (all returned lists will be sorted alphabetically)
* list 0-25: a,b,c,..,z
* list 26: 0-9
* list 27: other
*/
private static List<List<String>> gatesSortedByName(Collection<Gate> allGates) {
// create the lists
List<List<String>> ids = new ArrayList<>();
for (int i = 0; i < 28; i++) {
ids.add(new ArrayList<String>());
}
// put all gates into correct lists
for (Gate gate : allGates) {
String id = gate.getId();
int first = id.charAt(0);
if (first > 96 && first < 123) { // convert lower case chars
first -= 97;
} else if (first > 64 && first < 91) { // convert upper case chars
first -= 65;
} else if (first > 47 && first < 58) { // convert numbers
first = 26;
} else { // everything else
first = 27;
}
ids.get(first).add(id);
}
// sort everything
for (int i = 0; i < 28; i++) {
Collections.sort(ids.get(i));
}
return ids;
}
/**
* Returns a list of strings.
* Each string is the text for a page.
* The maximum number of lines per page is 'linesPerPage' minus 1.
* Will return an empty list if no gates are availible.
*/
private List<String> pagedGateIds() {
Collection<Gate> gates = this.getAllGates();
if (gates.size() == 0) {
return null;
}
List<List<String>> gatesSortedByName = gatesSortedByName(gates);
List<String> allPages = new ArrayList<>();
int linesLeftOnPage = linesPerPage - 1;
String currentPageString = "";
for (int i = 0; i < gatesSortedByName.size(); i++) {
List<String> currentGates = gatesSortedByName.get(i);
if (currentGates.isEmpty()) {
continue;
}
List<String> currentGatesAsLines = linesOfGateIds(currentGates);
boolean moreGatesOnLastPage = false;
while (!currentGatesAsLines.isEmpty()) {
if (linesLeftOnPage < 2) {
currentPageString = currentPageString.substring(0, currentPageString.length() - 2); // remove newlines add the end of the page
allPages.add(currentPageString);
currentPageString = "";
linesLeftOnPage = linesPerPage - 1;
}
// calculate number of lines to add to current page
int linesNecessaryForCurrentGates = currentGatesAsLines.size();
int linesToFill;
boolean moreGatesOnNextPage;
if (linesNecessaryForCurrentGates < linesLeftOnPage) {
linesToFill = linesNecessaryForCurrentGates;
moreGatesOnNextPage = false;
} else {
linesToFill = linesLeftOnPage - 1;
moreGatesOnNextPage = true;
}
// add title
currentPageString += intToTitleString(i, moreGatesOnLastPage, moreGatesOnNextPage);
currentPageString += ChatColor.AQUA;
linesLeftOnPage--;
// add gate lines
for (int j = 0; j < linesToFill; j++) {
currentPageString += currentGatesAsLines.get(j) + "\n";
}
// remove lines added
for (int j = 0; j < linesToFill; j++) {
currentGatesAsLines.remove(0);
}
// cleanup
moreGatesOnLastPage = linesNecessaryForCurrentGates >= linesLeftOnPage;
linesLeftOnPage -= linesToFill;
}
}
// add the last page
if (!currentPageString.isEmpty()) {
currentPageString = currentPageString.substring(0, currentPageString.length() - 2); // remove newlines add the end of the page
allPages.add(currentPageString);
}
return allPages;
}
private int getPageParameter() {
int page = 1;
try {
page = new Integer(parameters.get(0));
} catch (Exception ignored) {
}
return page;
}
} }

View File

@ -0,0 +1,70 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.commands;
import java.util.Set;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.block.Block;
public class CommandLocation extends BaseLocationCommand {
public CommandLocation() {
aliases.add("location");
aliases.add("lo");
requiredParameters.add("id");
helpDescription = "Set the entrance of the gate to your current location.";
requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = true;
shouldPersistToDisk = true;
senderMustBePlayer = true;
}
public void perform() {
Location playerLocation = getValidPlayerLocation();
if (playerLocation == null) {
sendMessage("There is not enough room for a gate to open here");
return;
}
Location oldLocation = gate.getLocation();
Set<Location> oldGateBlockLocations = gate.getGateBlockLocations();
Set<Block> oldFrameBlocks = gate.getGateFrameBlocks();
try {
if (gate.isOpen()) {
GateBlockChangeSender.updateGateBlocks(gate, true);
}
gate.setLocation(playerLocation);
sendMessage(ChatColor.GREEN + "The location of '" + gate.getId() + "' is now at your current location.");
} catch (Exception e) {
sendMessage(ChatColor.RED + "There seems to be no frame at your new location! The gate got closed!" + ChatColor.AQUA + " You should build a frame now and execute:");
sendMessage(new CommandTriggerOpen().getUsageTemplate(true));
} finally {
gatesManager.handleGateLocationChange(gate, oldLocation, oldGateBlockLocations, oldFrameBlocks);
GateBlockChangeSender.updateGateBlocks(gate);
}
}
}

View File

@ -0,0 +1,45 @@
package de.craftinc.gates.commands;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.models.GateMaterial;
import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor;
import java.security.InvalidParameterException;
public class CommandMaterial extends BaseCommand {
public CommandMaterial() {
aliases.add("material");
aliases.add("m");
requiredParameters.add("id");
requiredParameters.add("material");
senderMustBePlayer = false;
hasGateParam = true;
helpDescription = "Change the material of a gate";
requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
}
public void perform() {
GateMaterial material;
try {
material = new GateMaterial(parameters.get(1));
} catch (InvalidParameterException e) {
sendMessage(ChatColor.RED + "Invalid material!");
return;
}
try {
gate.setMaterial(material);
} catch (Exception e) {
sendMessage(ChatColor.RED + "Frame invalid. Gate is now closed!");
}
GateBlockChangeSender.updateGateBlocks(gate);
sendMessage(ChatColor.GREEN + "Gate " + gate.getId() + " uses now " + material.toString() + " as material.");
}
}

View File

@ -0,0 +1,41 @@
package de.craftinc.gates.commands;
import de.craftinc.gates.models.Gate;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.GateBlockChangeSender;
import de.craftinc.gates.util.TextUtil;
import java.util.ArrayList;
import java.util.Set;
public class CommandNearby extends BaseLocationCommand {
public CommandNearby() {
aliases.add("nearby");
aliases.add("nb");
helpDescription = "Highlight nearby gates";
requiredPermission = PermissionController.permissionInfo;
needsPermissionAtCurrentLocation = true;
shouldPersistToDisk = false;
senderMustBePlayer = true;
hasGateParam = false;
}
public void perform() {
Set<Gate> nearbyGates = gatesManager.getNearbyGates(player.getLocation().getChunk());
if (nearbyGates == null) {
player.sendMessage("There are no gates near you!");
} else {
GateBlockChangeSender.temporaryHighlightGatesFrames(player, nearbyGates);
ArrayList<String> gateNames = new ArrayList<>();
for (Gate g : nearbyGates) {
gateNames.add(g.getId());
}
player.sendMessage("Nearby gates: " + TextUtil.implode(gateNames, ", "));
}
}
}

View File

@ -0,0 +1,69 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.commands;
import de.craftinc.gates.controllers.PermissionController;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import de.craftinc.gates.models.Gate;
public class CommandNew extends BaseLocationCommand {
public CommandNew() {
aliases.add("new");
aliases.add("create");
aliases.add("n");
requiredParameters.add("id");
senderMustBePlayer = true;
hasGateParam = false;
helpDescription = "Create a gate at your current location.";
requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = true;
shouldPersistToDisk = true;
senderMustBePlayer = true;
}
public void perform() {
String id = parameters.get(0);
if (gatesManager.gateExists(id)) {
sendMessage(ChatColor.RED + "Creating the gate failed! " + "A gate with the supplied id already exists!");
return;
}
gate = new Gate(id);
sendMessage(ChatColor.GREEN + "Gate with id '" + id + "' was created.");
Location playerLocation = getValidPlayerLocation();
if (playerLocation != null) {
try {
gate.setLocation(playerLocation);
sendMessage(ChatColor.AQUA + "The gates location has been set to your current location.");
} catch (Exception ignored) {
}
} else {
sendMessage(ChatColor.RED + "Your location is invalid!" + ChatColor.AQUA + "Go somewhere else and execute:");
sendMessage(new CommandLocation().getUsageTemplate(true));
}
gatesManager.handleNewGate(gate);
}
}

View File

@ -1,42 +0,0 @@
package de.craftinc.gates.commands;
import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin;
public class CommandOpen extends BaseCommand
{
public CommandOpen()
{
aliases.add("open");
aliases.add("o");
requiredParameters.add("id");
helpDescription = "Open a gate so players can use it.";
requiredPermission = Plugin.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
senderMustBePlayer = false;
}
public void perform()
{
try
{
gate.setOpen(true);
sendMessage(ChatColor.GREEN + "The gate was opened.");
}
catch (Exception e)
{
sendMessage(ChatColor.RED + e.getMessage());
}
}
}

View File

@ -0,0 +1,48 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.commands;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor;
public class CommandRemove extends BaseCommand {
public CommandRemove() {
aliases.add("delete");
aliases.add("del");
aliases.add("remove");
requiredParameters.add("id");
senderMustBePlayer = false;
helpDescription = "Removes the gate from the game.";
requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
senderMustBePlayer = false;
}
public void perform() {
gatesManager.handleDeletion(gate);
GateBlockChangeSender.updateGateBlocks(gate, true);
sendMessage(ChatColor.GREEN + "Gate with id '" + gate.getId() + "' was deleted.");
}
}

View File

@ -1,48 +1,52 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.commands; package de.craftinc.gates.commands;
import de.craftinc.gates.controllers.PermissionController;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import de.craftinc.gates.Gate; public class CommandRename extends BaseCommand {
import de.craftinc.gates.Plugin;
public CommandRename() {
aliases.add("rename");
aliases.add("rn");
public class CommandRename extends BaseCommand hasGateParam = true;
{ senderMustBePlayer = false;
public CommandRename() requiredParameters.add("current name");
{ requiredParameters.add("new name");
aliases.add("rename"); helpDescription = "Changes the id of a gate.";
aliases.add("changename"); requiredPermission = PermissionController.permissionManage;
aliases.add("cn"); needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
hasGateParam = true; }
senderMustBePlayer = false;
requiredParameters.add("current name");
requiredParameters.add("new name");
helpDescription = "Changes the id of a gate.";
requiredPermission = Plugin.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
senderMustBePlayer = false;
}
public void perform()
{
String newId = parameters.get(1);
try
{
Gate.rename(gate.getId(), newId);
sendMessage(ChatColor.GREEN + "Gate " + gate.getId() + " is now known as " + newId + ".");
}
catch (Exception e)
{
sendMessage(ChatColor.RED + "Cannot rename " + gate.getId() + ". There is already a gate named " + newId + ".");
}
}
public void perform() {
String newId = parameters.get(1);
if (gatesManager.gateExists(newId)) {
sendMessage(ChatColor.RED + "Cannot rename " + gate.getId() + ". There is already a gate named " + newId + ".");
} else {
String oldId = gate.getId();
gate.setId(newId);
gatesManager.handleGateIdChange(gate, oldId);
sendMessage(ChatColor.GREEN + "Gate " + gate.getId() + " is now known as " + newId + ".");
}
}
} }

View File

@ -1,48 +0,0 @@
package de.craftinc.gates.commands;
import java.util.logging.Level;
import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin;
public class CommandSetExit extends BaseCommand
{
public CommandSetExit()
{
aliases.add("exit");
aliases.add("e");
requiredParameters.add("id");
helpDescription = "Change exit of location.";
requiredPermission = Plugin.permissionManage;
needsPermissionAtCurrentLocation = true;
shouldPersistToDisk = true;
senderMustBePlayer = true;
}
public void perform()
{
try
{
System.out.println(gate.getExit());
gate.setExit(player.getLocation());
sendMessage(ChatColor.GREEN + "The exit of gate '" + gate.getId() + "' is now where you stand.");
System.out.println(gate.getExit());
}
catch (Exception e) {
sendMessage(ChatColor.RED + "Setting the exit for the gate failed! See server log for more information");
Plugin.log(Level.WARNING, e.getMessage());
e.printStackTrace();
}
}
}

View File

@ -1,43 +0,0 @@
package de.craftinc.gates.commands;
import java.util.logging.Level;
import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin;
public class CommandSetHidden extends BaseCommand
{
public CommandSetHidden()
{
aliases.add("hide");
aliases.add("h");
requiredParameters.add("id");
helpDescription = "Makes a gate NOT consist of gate blocks while open.";
requiredPermission = Plugin.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
senderMustBePlayer = false;
}
public void perform()
{
try
{
gate.setHidden(true);
sendMessage(ChatColor.GREEN + "The gate '" + gate.getId() + "' is now hidden.");
}
catch (Exception e)
{
sendMessage(ChatColor.RED + "Hiding the gate failed! See server log for more information");
Plugin.log(Level.WARNING, e.getMessage());
e.printStackTrace();
}
}
}

View File

@ -1,56 +0,0 @@
package de.craftinc.gates.commands;
import java.util.logging.Level;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import de.craftinc.gates.Plugin;
public class CommandSetLocation extends BaseLocationCommand
{
public CommandSetLocation()
{
aliases.add("location");
aliases.add("l");
requiredParameters.add("id");
helpDescription = "Set the entrance of the gate to your current location.";
requiredPermission = Plugin.permissionManage;
needsPermissionAtCurrentLocation = true;
shouldPersistToDisk = true;
senderMustBePlayer = true;
}
public void perform()
{
Location playerLocation = getValidPlayerLocation();
if (playerLocation == null)
{
sendMessage("There is not enough room for a gate to open here");
return;
}
try
{
gate.setLocation(playerLocation);
sendMessage(ChatColor.GREEN + "The location of '" + gate.getId() + "' is now at your current location.");
}
catch (Exception e)
{
sendMessage(ChatColor.RED + "Setting the location for the gate failed! See server log for more information");
Plugin.log(Level.WARNING, e.getMessage());
e.printStackTrace();
}
}
}

View File

@ -1,42 +0,0 @@
package de.craftinc.gates.commands;
import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin;
public class CommandSetVisible extends BaseCommand
{
public CommandSetVisible()
{
aliases.add("unhide");
aliases.add("uh");
requiredParameters.add("id");
helpDescription = "Make that gate visible";
requiredPermission = Plugin.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
senderMustBePlayer = false;
}
public void perform()
{
try
{
gate.setHidden(false);
sendMessage(ChatColor.GREEN + "The gate " + gate.getId() + " is now visible.");
}
catch (Exception e) {
sendMessage(ChatColor.RED + e.getMessage());
}
}
}

View File

@ -0,0 +1,23 @@
package de.craftinc.gates.commands;
import de.craftinc.gates.controllers.PermissionController;
public class CommandTeleport extends BaseCommand {
public CommandTeleport() {
aliases.add("teleport");
aliases.add("t");
requiredParameters.add("id");
senderMustBePlayer = true;
hasGateParam = true;
helpDescription = "Teleport to the location of a gate";
requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = false;
}
public void perform() {
}
}

View File

@ -0,0 +1,54 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.commands;
import de.craftinc.gates.controllers.PermissionController;
import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor;
public class CommandTriggerOpen extends BaseCommand {
public CommandTriggerOpen() {
aliases.add("triggerOpen");
aliases.add("o");
requiredParameters.add("id");
helpDescription = "Open/close a gate.";
requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
senderMustBePlayer = false;
}
public void perform() {
try {
if (!gate.isOpen() && gate.getExit() == null && player != null) {
gate.setExit(player.getLocation());
sendMessage(ChatColor.GREEN + "The exit of gate '" + gate.getId() + "' is now where you stand.");
}
gate.setOpen(!gate.isOpen());
GateBlockChangeSender.updateGateBlocks(gate);
gatesManager.handleGateLocationChange(gate, null, null, null);
sendMessage(ChatColor.GREEN + "The gate is now " + (gate.isOpen() ? "open." : "closed."));
} catch (Exception e) {
sendMessage(ChatColor.RED + e.getMessage());
}
}
}

View File

@ -0,0 +1,47 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.commands;
import de.craftinc.gates.controllers.PermissionController;
import org.bukkit.ChatColor;
public class CommandTriggerVehicles extends BaseCommand {
public CommandTriggerVehicles() {
aliases.add("vehicles");
aliases.add("v");
requiredParameters.add("id");
helpDescription = "Allow/deny players to travel while riding.";
requiredPermission = PermissionController.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
senderMustBePlayer = false;
}
@Override
protected void perform() {
gate.setAllowsVehicles(gate.getAllowsVehicles());
if (gate.getAllowsVehicles()) {
sendMessage(ChatColor.GREEN + "Traveling while riding is now enabled for this gate.");
} else {
sendMessage(ChatColor.GREEN + "Traveling while riding is now disabled for this gate.");
}
}
}

View File

@ -0,0 +1,477 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.controllers;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.models.Gate;
import de.craftinc.gates.persistence.MigrationUtil;
import de.craftinc.gates.util.ConfigurationUtil;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import de.craftinc.gates.models.SimpleChunk;
import de.craftinc.gates.models.SimpleLocation;
public class GatesManager {
protected List<Gate> gates;
private static final String gatesPath = "gates"; // path to gates inside the yaml file
private static final String storageVersionPath = "version";
private static final int storageVersion = 3;
private File gatesConfigFile;
private FileConfiguration gatesConfig;
private int chunkRadius;
private Map<String, Gate> gatesById;
private Map<SimpleChunk, Set<Gate>> gatesByChunk;
private Map<SimpleLocation, Gate> gatesByLocation;
private Map<SimpleLocation, Gate> gatesByFrameLocation;
private boolean storageFileIsInvalid = false;
public Gate getGateWithId(final String id) {
return gatesById.get(id.toLowerCase());
}
public Set<Gate> getNearbyGates(final Chunk chunk) {
SimpleChunk simpleChunk = new SimpleChunk(chunk);
return gatesByChunk.get(simpleChunk);
}
/**
* Returns the closest gate.
*
* @param location The location at which to look for a gate.
* @return Might return null if there are no nearby gates.
*/
public Gate getNearestGate(final Location location) {
Set<Gate> nearbyGates = getNearbyGates(location.getChunk());
if (nearbyGates == null) {
return null;
}
double minDist = Double.MAX_VALUE;
Gate nearestGate = null;
for (Gate g : nearbyGates) {
double dist = location.distance(g.getLocation());
if (dist < minDist) {
minDist = dist;
nearestGate = g;
}
}
return nearestGate;
}
Gate getGateAtLocation(final Location location) {
SimpleLocation simpleLocation = new SimpleLocation(location);
return gatesByLocation.get(simpleLocation);
}
public Gate getGateAtFrameLocation(final Location location) {
SimpleLocation simpleLocation = new SimpleLocation(location);
return gatesByFrameLocation.get(simpleLocation);
}
public void saveGatesToDisk() {
if (storageFileIsInvalid) {
Plugin.log(Level.SEVERE, "ERROR: Not saving gates to disk. Storage file is invalid or corrupted!");
return;
}
gatesConfig.set(gatesPath, gates);
gatesConfig.set(storageVersionPath, storageVersion);
try {
gatesConfig.save(gatesConfigFile);
Plugin.log("Saved gates to disk.");
} catch (IOException e) {
Plugin.log(Level.SEVERE, "ERROR: Could not save gates to disk.");
e.printStackTrace();
}
}
@SuppressWarnings("unchecked")
public boolean loadGatesFromDisk() {
// TODO: refactor: move loading/saving logic into persistence package
this.gatesConfigFile = new File(Plugin.getPlugin().getDataFolder(), "gates.yml");
if (!this.gatesConfigFile.exists()) {
try {
boolean isNew = this.gatesConfigFile.createNewFile();
if (isNew) {
Plugin.log(Level.FINEST, "Created gate storage file.");
}
} catch (IOException e) {
this.storageFileIsInvalid = true;
Plugin.log(Level.SEVERE, "Cannot create gate storage file! No gates will be persisted.");
return false;
}
}
this.gatesConfig = new YamlConfiguration();
try {
this.gatesConfig.load(this.gatesConfigFile);
} catch (Exception e) {
this.storageFileIsInvalid = true;
Plugin.log(Level.SEVERE, "Gate file on disk is invalid. No gates loaded. Plugin will be disabled! (" + Arrays.toString(e.getStackTrace()) + ")");
return false;
}
this.gates = (List<Gate>) gatesConfig.getList(gatesPath);
if (this.gates == null) {
this.gates = new ArrayList<>();
}
for (Object o : this.gates) {
if (!(o instanceof Gate)) {
this.storageFileIsInvalid = true;
Plugin.log(Level.SEVERE, "Gate file on disk is invalid. No gates loaded. Plugin will be disabled! (Invalid gate class detected)");
return false;
}
}
for (Gate g : this.gates) {
try {
g.validate();
} catch (Exception e) {
try {
g.setOpen(false);
} catch (Exception ignored) {
}
Plugin.log(Level.FINER, "closed gate '" + g.getId() + "' reason: " + e.getMessage());
}
}
fillGatesById();
fillGatesByChunk();
fillGatesByLocation();
fillGatesByFrameLocation();
Plugin.log("Loaded " + this.gates.size() + " gates.");
// migration
int fileStorageVersion = gatesConfig.getInt(storageVersionPath);
if (fileStorageVersion > storageVersion) {
this.storageFileIsInvalid = true;
Plugin.log(Level.SEVERE, "Unsupported storage version detected! Make sure you have the latest version of Craft Inc. Gates installed. Plugin will be disabled!");
return false;
}
if (fileStorageVersion < storageVersion && !this.gates.isEmpty()) {
Plugin.log("Outdated storage version detected. Performing data migration...");
boolean success = MigrationUtil.performMigration(fileStorageVersion, storageVersion, this.gates);
this.storageFileIsInvalid = !success;
return success;
}
return true;
}
private int getChunkRadius() {
if (this.chunkRadius == 0) {
this.chunkRadius = Plugin.getPlugin().getConfig().getInt(ConfigurationUtil.confPlayerGateBlockUpdateRadiusKey);
this.chunkRadius = this.chunkRadius >> 4;
}
return this.chunkRadius;
}
private void fillGatesById() {
gatesById = new HashMap<>((int) (gates.size() * 1.25));
for (Gate g : gates) {
this.addGateWithId(g);
}
}
private void fillGatesByChunk() {
HashSet<SimpleChunk> chunksUsedByGates = new HashSet<>();
for (Gate g : gates) {
if (g.getLocation() != null) {
Chunk c = g.getLocation().getChunk();
int x = c.getX();
int z = c.getZ();
for (int i = x - getChunkRadius(); i < x + getChunkRadius(); i++) {
for (int j = z - getChunkRadius(); j < z + getChunkRadius(); j++) {
chunksUsedByGates.add(new SimpleChunk(i, j, c.getWorld()));
}
}
}
}
gatesByChunk = new HashMap<>((int) (chunksUsedByGates.size() * 1.25));
for (Gate g : gates) {
this.addGateByChunk(g);
}
}
private void fillGatesByLocation() {
Set<Location> gateBlocks = new HashSet<>();
for (Gate g : gates) {
for (Location l : g.getGateBlockLocations()) {
gateBlocks.add(l);
Location headLocation = l.clone().add(0, 1, 0);
gateBlocks.add(headLocation);
}
}
gatesByLocation = new HashMap<>((int) (gateBlocks.size() * 1.25));
for (Gate g : gates) {
this.addGateByLocations(g);
}
}
private void fillGatesByFrameLocation() {
int numFrameBlocks = 0;
for (Gate g : gates) {
numFrameBlocks += g.getGateFrameBlocks().size();
}
gatesByFrameLocation = new HashMap<>((int) (numFrameBlocks * 1.25));
for (Gate g : gates) {
this.addGateByFrameLocations(g);
}
}
private void removeGateById(final String id) {
gatesById.remove(id);
}
private void addGateWithId(final Gate g) {
gatesById.put(g.getId(), g);
}
private void removeGateByLocation(final Set<Location> gateBlocks) {
if (gateBlocks != null) {
for (Location l : gateBlocks) {
SimpleLocation sl = new SimpleLocation(l);
gatesByLocation.remove(sl);
SimpleLocation headLocation = new SimpleLocation(l, true);
gatesByLocation.remove(headLocation);
}
}
}
private void removeGateByFrameLocation(final Set<Block> gateFrameBlocks) {
if (gateFrameBlocks != null) {
for (Block block : gateFrameBlocks) {
SimpleLocation sl = new SimpleLocation(block.getLocation());
gatesByFrameLocation.remove(sl);
}
}
}
private void addGateByLocations(final Gate g) {
for (Location l : g.getGateBlockLocations()) {
SimpleLocation sl = new SimpleLocation(l);
gatesByLocation.put(sl, g);
SimpleLocation headLocation = new SimpleLocation(l, true);
gatesByLocation.put(headLocation, g);
}
}
private void addGateByFrameLocations(final Gate g) {
for (Block block : g.getGateFrameBlocks()) {
SimpleLocation sl = new SimpleLocation(block.getLocation());
gatesByFrameLocation.put(sl, g);
}
}
private void removeGateFromChunk(final Gate g, final Location l) {
if (l != null) {
Chunk c = l.getChunk();
int x = c.getX();
int z = c.getZ();
for (int i = x - getChunkRadius(); i < x + getChunkRadius(); i++) {
for (int j = z - getChunkRadius(); j < z + getChunkRadius(); j++) {
SimpleChunk sc = new SimpleChunk(i, j, c.getWorld());
Set<Gate> gatesInChunk = gatesByChunk.get(sc);
if (gatesInChunk != null) {
gatesInChunk.remove(g);
}
}
}
}
}
private void addGateByChunk(final Gate g) {
Location gateLocation = g.getLocation();
if (gateLocation != null) {
Chunk c = g.getLocation().getChunk();
int x = c.getX();
int z = c.getZ();
for (int i = x - getChunkRadius(); i < x + getChunkRadius(); i++) {
for (int j = z - getChunkRadius(); j < z + getChunkRadius(); j++) {
SimpleChunk sc = new SimpleChunk(i, j, c.getWorld());
Set<Gate> gatesForC = gatesByChunk.get(sc);
if (gatesForC == null) {
gatesForC = new HashSet<>(); // NOTE: not optimizing size here
gatesByChunk.put(sc, gatesForC);
}
gatesForC.add(g);
}
}
}
}
public void storeInvalidGate(Map<String, Object> map) {
File invalidGatesFile = new File(Plugin.getPlugin().getDataFolder(), "invalid_gates.yml");
Boolean invalidGatesFileExists = invalidGatesFile.exists();
try {
FileWriter fileWriter = new FileWriter(invalidGatesFile, true);
if (!invalidGatesFileExists) {
fileWriter.write("gates:\n");
}
fileWriter.write("- ==: ");
fileWriter.write(map.get("==").toString() + "\n");
map.remove("==");
fileWriter.write("\topen: false\n");
map.remove("open");
fileWriter.write("\tgateBlocks: []\n");
map.remove("gateBlocks");
for (String key : map.keySet()) {
Object value = map.get(key);
fileWriter.write("\t" + key + ": ");
if (value instanceof Map) {
fileWriter.write("\n");
@SuppressWarnings("unchecked")
Map<String, Object> valueMap = (Map<String, Object>) value;
for (String k : valueMap.keySet()) {
Object v = valueMap.get(k);
fileWriter.write("\t\t" + k + ": " + v.toString() + "\n");
}
} else {
fileWriter.write(value.toString() + "\n");
}
}
fileWriter.close();
} catch (IOException e) {
Plugin.log("ERROR: Could not save invalid gates to disk. Reason: \n" + Arrays.toString(e.getStackTrace()));
}
}
public void handleGateIdChange(final Gate g, final String oldId) {
this.removeGateById(oldId);
this.addGateWithId(g);
}
public void handleGateLocationChange(final Gate g,
final Location oldLocation,
final Set<Location> oldGateBlockLocations,
final Set<Block> oldGateFrameBlocks) {
this.removeGateFromChunk(g, oldLocation);
this.addGateByChunk(g);
this.removeGateByLocation(oldGateBlockLocations);
this.addGateByLocations(g);
this.removeGateByFrameLocation(oldGateFrameBlocks);
this.addGateByFrameLocations(g);
}
public void handleGateExitChange(final Gate g, final Location oldExit) {
// nothing to do
}
public void handleNewGate(final Gate g) {
this.gates.add(g);
this.addGateByChunk(g);
this.addGateByLocations(g);
this.addGateWithId(g);
this.addGateByFrameLocations(g);
}
public void handleDeletion(final Gate g) {
this.gates.remove(g);
this.removeGateById(g.getId());
this.removeGateFromChunk(g, g.getLocation());
this.removeGateByLocation(g.getGateBlockLocations());
this.removeGateByFrameLocation(g.getGateFrameBlocks());
}
public boolean gateExists(final String id) {
return gatesById.containsKey(id.toLowerCase());
}
public List<Gate> allGates() {
return gates;
}
}

View File

@ -0,0 +1,58 @@
package de.craftinc.gates.controllers;
import de.craftinc.gates.models.Gate;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
public class PermissionController {
public static final String permissionInfo = "craftincgates.info";
public static final String permissionManage = "craftincgates.manage";
public static final String permissionUse = "craftincgates.use";
private Permission permission;
public void setPermission(Permission permission) {
this.permission = permission;
}
public boolean hasPermission(CommandSender sender, Gate gate, String permission) {
assert(sender != null);
assert(permission != null);
if (gate == null) {
return hasPermission(sender, permission);
}
final Location location = gate.getLocation();
final Location exit = gate.getExit();
boolean permAtLocation = location == null || hasPermission(sender, location.getWorld(), permission);
boolean permAtExit = exit == null || hasPermission(sender, exit.getWorld(), permission);
return permAtLocation && permAtExit;
}
public boolean hasPermission(CommandSender sender, String permission) {
return hasPermission(sender, (World)null, permission);
}
private boolean hasPermission(CommandSender sender, World world, String permission) {
assert(sender != null);
assert(permission != null);
if (this.permission == null) {
// fallback - use the standard bukkit permission system
return sender.hasPermission(permission);
}
if (!(sender instanceof OfflinePlayer)) {
return this.permission.has(sender, permission);
}
String worldName = world != null ? world.getName() : null;
return this.permission.playerHas(worldName, (OfflinePlayer)sender, permission);
}
}

View File

@ -0,0 +1,126 @@
package de.craftinc.gates.controllers;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.models.Gate;
import de.craftinc.gates.util.ConfigurationUtil;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerTeleportEvent;
import java.util.Calendar;
import java.util.HashMap;
public class TeleportController {
private TeleportMessageUtil messageUtil;
private GatesManager gatesManager;
private PermissionController permissionController;
public TeleportController(Plugin plugin) {
this.gatesManager = plugin.getGatesManager();
this.messageUtil = new TeleportMessageUtil(plugin.getConfig());
this.permissionController = plugin.getPermissionController();
}
/**
* Try teleporting a player at given location.
*/
public void teleport(final Player player, Location toLocation) {
final Gate gateAtLocation = gatesManager.getGateAtLocation(toLocation);
if ((gateAtLocation == null) || !gateAtLocation.isOpen()) {
return;
}
if (!permissionController.hasPermission(player, gateAtLocation, PermissionController.permissionUse)) {
messageUtil.sendNoPermissionMessage(player);
return;
}
this.teleportPlayer(player, gateAtLocation);
}
private void teleportPlayer(final Player player, final Gate gate) {
final Entity vehicle = player.getVehicle();
if (vehicle != null && !gate.getAllowsVehicles()) {
messageUtil.sendVehicleForbiddenMessage(player);
Plugin.log("no vehicle transport");
return;
}
final Location destination = calculateDestination(player, gate);
player.teleport(destination);
if (vehicle != null) {
vehicle.teleport(destination, PlayerTeleportEvent.TeleportCause.PLUGIN);
vehicle.setPassenger(player);
}
messageUtil.sendTeleportMessage(player);
}
private Location calculateDestination(Player player, Gate gate) {
final Location exit = gate.getExit();
final Location pLocation = player.getLocation();
final Float newYaw = exit.getYaw() - gate.getLocation().getYaw() + pLocation.getYaw();
return new Location(exit.getWorld(),
exit.getX(),
exit.getY(),
exit.getZ(),
newYaw,
pLocation.getPitch()
);
}
}
class TeleportMessageUtil {
private HashMap<String, Long> lastNoPermissionMessages = new HashMap<>();
private FileConfiguration config;
TeleportMessageUtil(FileConfiguration config) {
this.config = config;
}
void sendVehicleForbiddenMessage(Player player) {
if (!config.getBoolean(ConfigurationUtil.confShowTeleportNoPermissionMessageKey)) {
return;
}
final String notAllowedMessage = config.getString(ConfigurationUtil.confGateTeleportVehicleNotAllowedMessageKey);
player.sendMessage(ChatColor.DARK_AQUA + notAllowedMessage);
}
void sendNoPermissionMessage(Player player) {
if (!config.getBoolean(ConfigurationUtil.confShowTeleportNoPermissionMessageKey)) {
return;
}
final String playerName = player.getPlayer().getName();
if (playerName == null) {
return;
}
final Long now = Calendar.getInstance().getTimeInMillis();
// do not display messages more often than once per second
if (!this.lastNoPermissionMessages.containsKey(playerName)
|| this.lastNoPermissionMessages.get(playerName) < now - 10000L) {
final String noPermissionString = config.getString(ConfigurationUtil.confGateTeleportNoPermissionMessageKey);
player.sendMessage(ChatColor.RED + noPermissionString);
this.lastNoPermissionMessages.put(playerName, now);
}
}
void sendTeleportMessage(Player player) {
if (!config.getBoolean(ConfigurationUtil.confShowTeleportMessageKey)) {
return;
}
final String teleportMessage = config.getString(ConfigurationUtil.confGateTeleportMessageKey);
player.sendMessage(ChatColor.DARK_AQUA + teleportMessage);
}
}

View File

@ -0,0 +1,46 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.listeners;
import de.craftinc.gates.models.Gate;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
public class BlockBreakListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void onBlockBreak(BlockBreakEvent event) {
if (event.isCancelled()) {
return;
}
Gate gate = Plugin.getPlugin().getGatesManager().getGateAtFrameLocation(event.getBlock().getLocation());
if (gate != null && gate.getMaterial().getMaterial() != Material.AIR) {
try {
gate.setOpen(false);
} catch (Exception ignored) {}
GateBlockChangeSender.updateGateBlocks(gate);
}
}
}

View File

@ -0,0 +1,33 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.listeners;
import de.craftinc.gates.util.GateBlockChangeSender;
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.PlayerChangedWorldEvent;
public class PlayerChangedWorldListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerChangeWorld(PlayerChangedWorldEvent event) {
Player p = event.getPlayer();
GateBlockChangeSender.updateGateBlocks(p, p.getLocation());
}
}

View File

@ -0,0 +1,33 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.listeners;
import de.craftinc.gates.util.GateBlockChangeSender;
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.PlayerJoinEvent;
public class PlayerJoinListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerJoin(PlayerJoinEvent event) {
Player p = event.getPlayer();
GateBlockChangeSender.updateGateBlocks(p, p.getLocation());
}
}

View File

@ -0,0 +1,46 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.listeners;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.controllers.TeleportController;
import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
public class PlayerMoveListener implements Listener {
private TeleportController teleportController;
public PlayerMoveListener(Plugin plugin) {
this.teleportController = new TeleportController(plugin);
}
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerMove(PlayerMoveEvent event) {
if (event.isCancelled()) {
return;
}
if (event.getFrom().getChunk() != event.getTo().getChunk()) {
GateBlockChangeSender.updateGateBlocks(event.getPlayer(), event.getTo());
}
teleportController.teleport(event.getPlayer(), event.getTo());
}
}

View File

@ -0,0 +1,30 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.listeners;
import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerRespawnEvent;
public class PlayerRespawnListener implements Listener {
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerRespawn(PlayerRespawnEvent event) {
GateBlockChangeSender.updateGateBlocks(event.getPlayer(), event.getRespawnLocation(), true);
}
}

View File

@ -0,0 +1,35 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.listeners;
import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerTeleportEvent;
public class PlayerTeleportListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerTeleport(PlayerTeleportEvent event) {
if (event.isCancelled()) {
return;
}
GateBlockChangeSender.updateGateBlocks(event.getPlayer(), event.getTo(), true);
}
}

View File

@ -1,51 +0,0 @@
package de.craftinc.gates.listeners;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPhysicsEvent;
public class PluginBlockListener implements Listener
{
@EventHandler(priority = EventPriority.NORMAL)
public void onBlockPhysics(BlockPhysicsEvent event)
{
if (event.isCancelled())
return;
if (event.getBlock().getType() != Material.PORTAL) {
return;
}
if (isBlockInPortal(event.getBlock())) {
event.setCancelled(true);
}
}
public boolean isBlockInPortal(Block block)
{
if (block.getRelative(BlockFace.UP).getType() == Material.AIR) {
return false;
}
if (block.getRelative(BlockFace.DOWN).getType() == Material.AIR) {
return false;
}
if ( block.getRelative(BlockFace.NORTH).getType() != Material.AIR && block.getRelative(BlockFace.SOUTH).getType() != Material.AIR ) {
return true;
}
if ( block.getRelative(BlockFace.WEST).getType() != Material.AIR && block.getRelative(BlockFace.EAST).getType() != Material.AIR ) {
return true;
}
return false;
}
}

View File

@ -1,94 +0,0 @@
package de.craftinc.gates.listeners;
import java.util.logging.Level;
import org.bukkit.ChatColor;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import de.craftinc.gates.Gate;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.GateUtil;
public class PluginPlayerListener implements Listener
{
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerMove(PlayerMoveEvent event)
{
if (event.isCancelled()) {
return;
}
// Find the gate at the current location.
Gate gateAtLocation = GateUtil.getGateAtPlayerLocation(event.getTo());
if (gateAtLocation == null) {
return;
}
// Check for permission
if (!hasPermission(event.getPlayer(), gateAtLocation)) {
event.getPlayer().sendMessage(ChatColor.RED + "Sorry, you are not allowed to use this gate!");
return;
}
// Teleport the player
checkChunkLoad(gateAtLocation.getLocation().getBlock());
Location gateExit = gateAtLocation.getExit();
Location gateLocation = gateAtLocation.getLocation();
Location playerLocation = event.getPlayer().getLocation();
Float newYaw = gateExit.getYaw() - gateLocation.getYaw() + playerLocation.getYaw();
Location teleportToLocation = new Location( gateExit.getWorld(),
gateExit.getX(),
gateExit.getY(),
gateExit.getZ(),
newYaw,
playerLocation.getPitch() );
event.getPlayer().teleport(teleportToLocation);
event.setTo(teleportToLocation);
event.getPlayer().sendMessage(ChatColor.DARK_AQUA + "Thank you for traveling with Craft Inc. Gates.");
}
private void checkChunkLoad(Block b)
{
World w = b.getWorld();
Chunk c = b.getChunk();
if (!w.isChunkLoaded(c))
{
Plugin.log(Level.FINE, "Loading chunk: " + c.toString() + " on: " + w.toString());
w.loadChunk(c);
}
}
protected boolean hasPermission(Player player, Gate gate)
{
if (Plugin.permission == null) // fallback Ð use the standard bukkit permission system
{
return player.hasPermission(Plugin.permissionUse);
}
else {
boolean permAtLocation = Plugin.permission.has(gate.getLocation().getWorld(), player.getName(), Plugin.permissionUse);
boolean permAtExit = Plugin.permission.has(gate.getExit().getWorld(), player.getName(), Plugin.permissionUse);
return permAtLocation && permAtExit;
}
}
}

View File

@ -1,94 +0,0 @@
package de.craftinc.gates.listeners;
import java.util.HashMap;
import org.bukkit.GameMode;
import org.bukkit.Location;
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.EntityPortalEnterEvent;
import org.bukkit.event.player.PlayerPortalEvent;
import de.craftinc.gates.Gate;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.GateUtil;
public class PluginPortalListener implements Listener
{
private HashMap<Player, Gate> currentGateAtEvent = new HashMap<Player, Gate>();
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerPortal(PlayerPortalEvent event)
{
if (event.isCancelled())
{
return;
}
Location playerLocation = event.getPlayer().getLocation();
Gate gateAtLocation = GateUtil.getGateAtPlayerLocation(playerLocation);
// If the player's gamemode is creative no gate might be found!
// It seems like players get teleported on a move event when the 'to' location is
// inside a gate. This meens the location obtained earlier is NOT inside a gate.
if (gateAtLocation == null && event.getPlayer().getGameMode() == GameMode.CREATIVE)
{
gateAtLocation = this.currentGateAtEvent.get(event.getPlayer());
}
if (gateAtLocation != null)
{
event.setCancelled(true);
}
this.currentGateAtEvent.put(event.getPlayer(), null);
}
@EventHandler(priority = EventPriority.NORMAL)
public void onEntityPortalEnterEvent(EntityPortalEnterEvent event)
{
if (event.getEntity() instanceof Player)
{
Player player = (Player)event.getEntity();
if (player.getGameMode() == GameMode.CREATIVE)
{
if (this.currentGateAtEvent.get(player) != null)
{
return;
}
Location eventLocation = event.getLocation();
Gate closestGate = GateUtil.closestGate(eventLocation);
if (closestGate != null)
{
// Make sure gate and event locations are on the same height (y-value).
// Otherwise the distance will be messed up when players are flying.
// FIX ME: this could potentially let a nearby nether portal fail!
eventLocation.setY(closestGate.getLocation().getY());
double distToClosestGate = closestGate.getLocation().distance(eventLocation);
Plugin.log("closest gate: " + closestGate.getId());
Plugin.log("distance: " + distToClosestGate);
if (distToClosestGate < 2.0) {
this.currentGateAtEvent.put(player, closestGate);
return;
}
}
}
this.currentGateAtEvent.put(player, null);
}
}
}

View File

@ -0,0 +1,27 @@
package de.craftinc.gates.listeners;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.controllers.TeleportController;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.vehicle.VehicleMoveEvent;
public class VehicleMoveListener implements Listener {
private TeleportController teleportController;
public VehicleMoveListener(Plugin plugin) {
this.teleportController = new TeleportController(plugin);
}
@EventHandler(priority = EventPriority.NORMAL)
public void onVehicleMove(VehicleMoveEvent event) {
Entity passenger = event.getVehicle().getPassenger();
if (passenger instanceof Player) {
teleportController.teleport((Player)passenger, event.getTo());
}
}
}

View File

@ -0,0 +1,298 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.models;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.ConfigurationUtil;
import de.craftinc.gates.util.FloodUtil;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import java.util.*;
public class Gate implements ConfigurationSerializable {
private Location location; /* saving both location and gateBlockLocations is redundant but makes it easy to allow players to reshape gates */
private Set<Location> gateBlockLocations = new HashSet<>(); /* Locations of the blocks inside the gate */
private Set<Block> gateFrameBlocks = new HashSet<>();
private Location exit;
private boolean isOpen = false;
private boolean allowsVehicles = true;
private String id;
private GateMaterial material = new GateMaterial(Material.PORTAL);
/**
* You should never create two gates with the same 'id'. Also see 'setId(String id)'.
*
* @param id This parameter must not be 'null'. An exception will be thrown otherwise!
*/
public Gate(final String id) {
setId(id);
}
public String toString() {
return super.toString() + " " + this.getId();
}
public GateDirection getDirection() {
if (gateBlockLocations.isEmpty()) {
return null;
} else {
Block some = ((Location)gateBlockLocations.toArray()[0]).getBlock();
boolean east = gateBlockLocations.contains(some.getRelative(BlockFace.EAST).getLocation());
boolean west = gateBlockLocations.contains(some.getRelative(BlockFace.WEST).getLocation());
return east || west ? GateDirection.EastWest : GateDirection.NorthSouth;
}
}
public GateMaterial getMaterial() {
return material;
}
public void setMaterial(GateMaterial material) throws Exception {
this.material = material;
validate();
}
/**
* @return This method might return a 'null' data.
*/
public Location getLocation() {
return location;
}
/**
* @param location Supplying 'null' is permitted.
* @throws Exception Will throw an exception if the gate is open and an invalid (no gate frame) location is
* supplied. Note that the supplied 'location' will be set even if an exception is thrown. Note that this
* gate will be closed if an exception is thrown.
*/
public void setLocation(final Location location) throws Exception {
this.location = location;
if (isOpen) {
findPortalBlocks();
validate();
} else {
this.gateBlockLocations = new HashSet<>();
this.gateFrameBlocks = new HashSet<>();
}
}
/**
* @return This method might return a 'null' value.
*/
public Location getExit() {
return exit;
}
/**
* @param exit Supplying 'null' is permitted.
* @throws Exception An exception will be thrown if 'null' data is supplied and this gate is open. Note that the
* supplied 'exit' will be set even if an exception is thrown. Note that this gate will be closed if an
* exception is thrown.
*/
public void setExit(final Location exit) throws Exception {
this.exit = exit;
validate();
}
/**
* @return This method will never return 'null'.
*/
public String getId() {
return id;
}
/**
* Every gate should have an unique 'id'. You should therefore check if another gate with the same 'id' exists.
* Note that this method will not check if another gate with the same 'id' exists!
*
* @param id This parameter must not be 'null'. An exception will be thrown otherwise!
*/
public void setId(final String id) {
if (id == null) {
throw new IllegalArgumentException("gate 'id' cannot be 'null'");
}
this.id = id.toLowerCase();
}
public boolean isOpen() {
return isOpen;
}
public void setOpen(boolean isOpen) throws Exception {
if (isOpen && !this.isOpen) {
findPortalBlocks();
}
this.isOpen = isOpen;
validate();
}
public void setAllowsVehicles(boolean allowsVehicles) {
this.allowsVehicles = allowsVehicles;
}
public boolean getAllowsVehicles() {
return this.allowsVehicles;
}
/**
* @return Will never return 'null' but might return an empty Set.
*/
public Set<Location> getGateBlockLocations() {
return gateBlockLocations;
}
/**
* @return Will never return 'null' but might return an empty Set.
*/
public Set<Block> getGateFrameBlocks() {
return gateFrameBlocks;
}
private void findPortalBlocks() {
gateBlockLocations = new HashSet<>();
Set<Block> gateBlocks = FloodUtil.getGatePortalBlocks(location.getBlock());
if (gateBlocks != null) {
for (Block b : gateBlocks) {
gateBlockLocations.add(b.getLocation());
}
}
gateFrameBlocks = FloodUtil.getFrame(gateBlocks);
}
/**
* Checks if values attributes do add up; will close gate on wrong values.
*/
public void validate() throws Exception {
if (!isOpen) {
return;
}
if (location == null) {
isOpen = false;
this.gateBlockLocations = new HashSet<>();
this.gateFrameBlocks = new HashSet<>();
throw new Exception("Gate got closed. It has no location.");
}
if (exit == null) {
isOpen = false;
this.gateBlockLocations = new HashSet<>();
this.gateFrameBlocks = new HashSet<>();
throw new Exception("Gate got closed. It has no exit.");
}
if (gateBlockLocations.size() == 0) {
isOpen = false;
this.gateBlockLocations = new HashSet<>();
this.gateFrameBlocks = new HashSet<>();
throw new Exception("Gate got closed. The frame is missing or broken. (no gate blocks)");
}
validateFrame();
}
private void validateFrame() throws Exception {
boolean isAir = material.getMaterial() == Material.AIR;
boolean ignore = !Plugin.getPlugin().getConfig().getBoolean(ConfigurationUtil.confCheckForBrokenGateFramesKey);
if (isAir || ignore) {
return;
}
for (Block b : gateFrameBlocks) {
if (b.getType() == Material.AIR) {
isOpen = false;
this.gateBlockLocations = new HashSet<>();
this.gateFrameBlocks = new HashSet<>();
throw new Exception("Gate got closed. The frame is missing or broken. (missing frame block(s))");
}
}
}
/*
* INTERFACE: ConfigurationSerializable
*/
static private String idKey = "id";
static private String locationKey = "location";
static private String gateBlocksKey = "gateBlocks";
static private String exitKey = "exit";
static private String materialKey = "material";
static private String isOpenKey = "open";
static private String allowsVehiclesKey = "allowsVehiclesKey";
@SuppressWarnings("unchecked")
public Gate(Map<String, Object> map) {
try {
id = map.get(idKey).toString().toLowerCase();
location = (Location) map.get(locationKey);
exit = (Location) map.get(exitKey);
material = new GateMaterial((String)map.get(materialKey));
isOpen = (Boolean) map.get(isOpenKey);
allowsVehicles = (Boolean) map.get(allowsVehiclesKey);
gateBlockLocations = (Set<Location>) map.get(gateBlocksKey);
gateFrameBlocks = FloodUtil.getFrameWithLocations(gateBlockLocations);
} catch (Exception e) {
Plugin.log("ERROR: Failed to load gate '" + id + "'! (" + e.getMessage() + ")");
Plugin.log("NOTE: This gate will be removed from 'gates.yml' and added to 'invalid_gates.yml'!");
Plugin.getPlugin().getGatesManager().storeInvalidGate(map);
}
try {
validate(); // make sure to not write invalid stuff to disk
} catch (Exception e) {
Plugin.log("The loaded gate " + this.getId() + " seems to be not valid: " + e.getMessage());
}
}
public Map<String, Object> serialize() {
Map<String, Object> retVal = new HashMap<>();
retVal.put(idKey, id);
retVal.put(isOpenKey, isOpen);
retVal.put(allowsVehiclesKey, allowsVehicles);
retVal.put(gateBlocksKey, gateBlockLocations);
retVal.put(materialKey, material.toString());
if (exit != null) {
retVal.put(exitKey, exit);
}
if (location != null) {
retVal.put(locationKey, location);
}
return retVal;
}
}

View File

@ -0,0 +1,6 @@
package de.craftinc.gates.models;
public enum GateDirection {
EastWest,
NorthSouth
}

View File

@ -0,0 +1,162 @@
package de.craftinc.gates.models;
import org.bukkit.Material;
import java.security.InvalidParameterException;
public class GateMaterial {
private Material material;
GateMaterial(Material material) {
this.material = material;
}
public GateMaterial(String materialString) throws InvalidParameterException {
Material material;
switch (materialString) {
case "air":
material = Material.AIR;
break;
case "sapling":
material = Material.SAPLING;
break;
case "water":
material = Material.STATIONARY_WATER;
break;
case "lava":
material = Material.STATIONARY_LAVA;
break;
case "cobweb":
material = Material.WEB;
break;
case "grass":
material = Material.LONG_GRASS;
break;
case "dead bush":
material = Material.DEAD_BUSH;
break;
case "dandelion":
material = Material.YELLOW_FLOWER;
break;
case "poppy":
material = Material.RED_ROSE;
break;
case "brown mushroom":
material = Material.BROWN_MUSHROOM;
break;
case "red mushroom":
material = Material.RED_MUSHROOM;
break;
case "torch":
material = Material.TORCH;
break;
case "redstone torch (off)":
material = Material.REDSTONE_TORCH_OFF;
break;
case "redstone torch (on)":
material = Material.REDSTONE_TORCH_ON;
break;
case "fence":
material = Material.FENCE;
break;
case "nether portal":
material = Material.PORTAL;
break;
case "iron bars":
material = Material.IRON_FENCE;
break;
case "glass pane":
material = Material.THIN_GLASS;
break;
case "fence gate":
material = Material.FENCE_GATE;
break;
case "nether brick fence":
material = Material.NETHER_FENCE;
break;
case "nether wart":
material = Material.NETHER_WARTS;
break;
case "end portal":
material = Material.ENDER_PORTAL;
break;
case "cobblestone wall":
material = Material.COBBLE_WALL;
break;
default:
throw new InvalidParameterException();
}
this.material = material;
}
@Override
public String toString() {
switch (material) {
case AIR:
return "air";
case SAPLING:
return "sapling";
case STATIONARY_WATER:
return "water";
case STATIONARY_LAVA:
return "lava";
case WEB:
return "cobweb";
case LONG_GRASS:
return "grass";
case DEAD_BUSH:
return "dead bush";
case YELLOW_FLOWER:
return "dandelion";
case RED_ROSE:
return "poppy";
case BROWN_MUSHROOM:
return "brown mushroom";
case RED_MUSHROOM:
return "red mushroom";
case TORCH:
return "torch";
case REDSTONE_TORCH_OFF:
return "redstone torch (off)";
case REDSTONE_TORCH_ON:
return "redstone torch (on)";
case FENCE:
return "fence";
case PORTAL:
return "nether portal";
case IRON_FENCE:
return "iron bars";
case THIN_GLASS:
return "glass pane";
case FENCE_GATE:
return "fence gate";
case NETHER_FENCE:
return "nether brick fence";
case NETHER_WARTS:
return "nether wart";
case ENDER_PORTAL:
return "end portal";
case COBBLE_WALL:
return "cobblestone wall";
default:
return "nether portal";
}
}
public Material getMaterial() {
return material;
}
public byte getData(GateDirection direction) {
switch (material) {
case PORTAL:
return direction == GateDirection.EastWest ? (byte)0b0 : (byte)0b10;
case GRASS:
return 1;
default:
return 0;
}
}
}

View File

@ -0,0 +1,73 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.models;
import org.bukkit.Chunk;
import org.bukkit.World;
public class SimpleChunk {
private int x;
private int z;
private String world;
public SimpleChunk(Chunk c) {
this.x = c.getX();
this.z = c.getZ();
this.world = c.getWorld().getName();
}
public SimpleChunk(int x, int z, World w) {
this.x = x;
this.z = z;
this.world = w.getName();
}
@Override
public boolean equals(Object o) {
if (o instanceof SimpleChunk) {
SimpleChunk otherLocation = (SimpleChunk) o;
if (otherLocation.x == this.x
&& otherLocation.z == this.z
&& otherLocation.world.equals(this.world)) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
int hash = 11;
hash = 29 * hash + x;
hash = 37 * hash + z;
hash = 29 * hash + world.hashCode();
return hash;
}
@Override
public String toString() {
return this.getClass().toString() + " (x=" + this.x + " z=" + this.z + " world='" + this.world + "')";
}
}

View File

@ -0,0 +1,83 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.models;
import org.bukkit.Location;
public class SimpleLocation {
private String world;
private int x;
private int y;
private int z;
public SimpleLocation(Location l) {
this.world = l.getWorld().getName();
// Using Block coordinates makes it possible to compare block locations with player locations.
// There might be an offset of 1 otherwise.
this.x = l.getBlockX();
this.y = l.getBlockY();
this.z = l.getBlockZ();
}
public SimpleLocation(Location l, boolean isHeadPosition) {
this.world = l.getWorld().getName();
// Using Block coordinates makes it possible to compare block locations with player locations.
// There might be an offset of 1 otherwise.
this.x = l.getBlockX();
this.y = l.getBlockY();
this.z = l.getBlockZ();
if (isHeadPosition) {
this.y--;
}
}
@Override
public String toString() {
return super.toString() + " x: " + x + " y: " + y + " z: " + z + " world: " + world;
}
@Override
public boolean equals(final Object o) {
if (o instanceof SimpleLocation) {
SimpleLocation otherLocation = (SimpleLocation) o;
if (otherLocation.x == this.x
&& otherLocation.y == this.y
&& otherLocation.z == this.z
&& otherLocation.world.equals(this.world)) {
return true;
}
}
return false;
}
@Override
public int hashCode() {
int hash = 13;
hash = 37 * hash + x;
hash = 31 * hash + y;
hash = 37 * hash + z;
hash = 31 * hash + world.hashCode();
return hash;
}
}

View File

@ -0,0 +1,40 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.persistence;
import de.craftinc.gates.models.Gate;
import de.craftinc.gates.Plugin;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import java.util.List;
import java.util.logging.Level;
public class MigrationUtil {
public static boolean performMigration(int storageVersion, int currentVersion, List<Gate> gates) {
if (storageVersion != currentVersion) {
Plugin.log(Level.SEVERE, "Supplied storage version is currently not supported!" +
"Make sure you have the latest version of Craft Inc. Gates installed. Plugin will be disabled!");
return false;
}
return true;
}
}

View File

@ -0,0 +1,30 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.util;
public class ConfigurationUtil {
public static final String confMaxGateBlocksKey = "maxGateBlocks";
public static final String confPlayerGateBlockUpdateRadiusKey = "playerGateBlockUpdateRadius";
public static final String confCheckForBrokenGateFramesKey = "checkForBrokenGateFrames";
public static final String confGateTeleportMessageKey = "gateTeleportMessage";
public static final String confGateTeleportVehicleNotAllowedMessageKey = "gateTeleportVehicleNotAllowedMessage";
public static final String confShowTeleportMessageKey = "showTeleportMessage";
public static final String confGateTeleportNoPermissionMessageKey = "gateTeleportNoPermissionMessage";
public static final String confShowTeleportNoPermissionMessageKey = "showTeleportNoPermissionMessage";
public static final String confSaveOnChangesKey = "saveOnChanges";
public static final String confHighlightDurationKey = "highlightDuration";
}

View File

@ -1,9 +1,26 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.util; package de.craftinc.gates.util;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.BlockFace; import org.bukkit.block.BlockFace;
@ -11,87 +28,170 @@ import org.bukkit.block.BlockFace;
import de.craftinc.gates.Plugin; import de.craftinc.gates.Plugin;
public class FloodUtil public class FloodUtil {
{ private static final Set<BlockFace> exp1 = new HashSet<>();
private final static int frameBlockSearchLimit = 40; private static final Set<BlockFace> exp2 = new HashSet<>();
private static final Set<BlockFace> exp1 = new HashSet<BlockFace>(); static {
private static final Set<BlockFace> exp2 = new HashSet<BlockFace>(); exp1.add(BlockFace.UP);
exp1.add(BlockFace.DOWN);
static exp1.add(BlockFace.EAST);
{ exp1.add(BlockFace.WEST);
exp1.add(BlockFace.UP);
exp1.add(BlockFace.DOWN); exp2.add(BlockFace.UP);
exp1.add(BlockFace.EAST); exp2.add(BlockFace.DOWN);
exp1.add(BlockFace.WEST); exp2.add(BlockFace.NORTH);
exp2.add(BlockFace.SOUTH);
exp2.add(BlockFace.UP); }
exp2.add(BlockFace.DOWN);
exp2.add(BlockFace.NORTH); /**
exp2.add(BlockFace.SOUTH); * Returns the all frame blocks of an gate.
} *
* @param blocks All blocks inside the gate.
* @return A Set containing all frame block. Will never return 'null'.
// For the same frame and location this set of blocks is deterministic */
public static Set<Block> getGateFrameBlocks(Block block) public static Set<Block> getFrame(final Set<Block> blocks) {
{ if (blocks == null || blocks.isEmpty()) {
Set<Block> blocks1 = getAirFloodBlocks(block, new HashSet<Block>(), exp1, frameBlockSearchLimit); return new HashSet<>();
Set<Block> blocks2 = getAirFloodBlocks(block, new HashSet<Block>(), exp2, frameBlockSearchLimit); }
if (blocks1 == null && blocks2 == null) // try to find gate's direction (north-south or east-west)
{ Set<BlockFace> gateFrameSearchFaces = null;
return null;
} for (Block b : blocks) {
if (blocks1 == null) if (blocks.contains(b.getRelative(BlockFace.EAST)) ||
{ blocks.contains(b.getRelative(BlockFace.WEST))) {
return blocks2;
} gateFrameSearchFaces = exp1;
break;
if (blocks2 == null) }
{
return blocks1; if (blocks.contains(b.getRelative(BlockFace.NORTH)) ||
} blocks.contains(b.getRelative(BlockFace.SOUTH))) {
if (blocks1.size() > blocks2.size()) gateFrameSearchFaces = exp2;
{ break;
return blocks2; }
}
}
return blocks1;
} if (gateFrameSearchFaces != null) {
return _getFrame(blocks, gateFrameSearchFaces);
} else { // no direction found (the gate might only consist of blocks one over another)
private static Set<Block> getAirFloodBlocks(Block startBlock, Set<Block> foundBlocks, Set<BlockFace> expandFaces, int limit)
{ // Try one direction and check if the found blocks are not air.
if (foundBlocks == null) // If air is found (frame broken or wrong direction) return the other direction
{ Set<Block> frameBlocks = _getFrame(blocks, exp1);
return null;
} for (Block b : frameBlocks) {
if (foundBlocks.size() > limit) if (b.getType() == Material.AIR) {
{ return _getFrame(blocks, exp2);
Plugin.log(Level.ALL, "exceeding gate size limit."); }
return null; }
}
return frameBlocks;
if (foundBlocks.contains(startBlock)) }
return foundBlocks; }
if (startBlock.getType() == Material.AIR || startBlock.getType() == Material.PORTAL)
{ private static Set<Block> _getFrame(final Set<Block> blocks, final Set<BlockFace> searchDirections) {
// ... We found a block :D ... Set<Block> frameBlocks = new HashSet<>();
foundBlocks.add(startBlock);
for (Block b : blocks) {
// ... And flood away !
for (BlockFace face : expandFaces) for (BlockFace bf : searchDirections) {
{ Block bb = b.getRelative(bf);
Block potentialBlock = startBlock.getRelative(face);
foundBlocks = getAirFloodBlocks(potentialBlock, foundBlocks, expandFaces, limit); if (!blocks.contains(bb)) {
} frameBlocks.add(bb);
} }
}
return foundBlocks; }
}
return frameBlocks;
}
/**
* Returns the all frame blocks of an gate.
*
* @param locations All locations inside the gate.
* @return A Set containing all frame block. Will never return 'null'.
*/
public static Set<Block> getFrameWithLocations(final Set<Location> locations) {
if (locations == null) {
throw new IllegalArgumentException("'locations' must not be 'null'");
}
Set<Block> blocks = new HashSet<>();
for (Location l : locations) {
blocks.add(l.getBlock());
}
return getFrame(blocks);
}
// For the same frame and location this set of blocks is deterministic
public static Set<Block> getGatePortalBlocks(final Block block) {
if (block == null) {
throw new IllegalArgumentException("'block' must not be 'null'");
}
int frameBlockSearchLimit = Plugin.getPlugin().getConfig().getInt(ConfigurationUtil.confMaxGateBlocksKey);
Set<Block> blocks1 = getAirFloodBlocks(block, new HashSet<Block>(), exp1, frameBlockSearchLimit);
Set<Block> blocks2 = getAirFloodBlocks(block, new HashSet<Block>(), exp2, frameBlockSearchLimit);
if (blocks1 == null && blocks2 == null) {
return null;
}
if (blocks1 == null) {
return blocks2;
}
if (blocks2 == null) {
return blocks1;
}
if (blocks1.size() > blocks2.size()) {
return blocks2;
}
return blocks1;
}
private static Set<Block> getAirFloodBlocks(final Block startBlock,
Set<Block> foundBlocks,
final Set<BlockFace> expandFaces,
int limit) {
if (foundBlocks == null) {
return null;
}
if (foundBlocks.size() > limit) {
Plugin.log(Level.ALL, "exceeding gate size limit.");
return null;
}
if (foundBlocks.contains(startBlock)) {
return foundBlocks;
}
if (startBlock.getType() == Material.AIR) {
foundBlocks.add(startBlock);
for (BlockFace face : expandFaces) {
Block potentialBlock = startBlock.getRelative(face);
foundBlocks = getAirFloodBlocks(potentialBlock, foundBlocks, expandFaces, limit);
}
}
return foundBlocks;
}
} }

View File

@ -0,0 +1,174 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.util;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.models.Gate;
import de.craftinc.gates.models.GateMaterial;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import java.util.ArrayList;
import java.util.Set;
import static de.craftinc.gates.util.ConfigurationUtil.*;
public class GateBlockChangeSender {
/**
* Replaces gate frame blocks with glowstone for a short period of time.
* Uses the data stored in 'highlightDuration' inside the config file
* for determining when to de-highlight the frames.
*
* @param player The player for whom the frame should be highlighted.
* Must not be null!
*
* @param gates The gates to highlighting
*/
public static void temporaryHighlightGatesFrames(final Player player, final Set<Gate> gates) {
assert(player != null);
assert(gates != null);
for (Gate g : gates) {
Set<Block> frameBlocks = g.getGateFrameBlocks();
for (Block b : frameBlocks) {
player.sendBlockChange(b.getLocation(), Material.GLOWSTONE, (byte) 0);
}
}
scheduleDelighting(player, gates);
}
/**
* Sends gate blocks to player at a given location. Will send the updates either immediately or
* immediately and after a short delay.
*
* @param player A player to send block changes to. Must not be null!
* @param location The location to look for gates nearby. Must not be null!
* @param sendDelayed Set to 'true' if the block changes shall be send a second time after a one
* second delay.
*/
public static void updateGateBlocks(final Player player, final Location location, boolean sendDelayed) {
assert(player != null);
assert(location != null);
Set<Gate> gatesNearby = Plugin.getPlugin().getGatesManager().getNearbyGates(location.getChunk());
if (gatesNearby == null) {
return; // no gates nearby
}
for (Gate g : gatesNearby) {
if (!g.isOpen()) {
continue;
}
sendGateBlockChanges(g, true, player);
}
if (sendDelayed) {
Bukkit.getScheduler().scheduleSyncDelayedTask(Plugin.getPlugin(), new Runnable() {
@Override
public void run() {
updateGateBlocks(player, location, false);
}
}, 20L);
}
}
public static void updateGateBlocks(final Player player, final Location location) {
updateGateBlocks(player, location, false);
}
public static void updateGateBlocks(final Gate gate) {
updateGateBlocks(gate, false);
}
/**
* Sends block changes to players near a given gate.
*
* @param gate Must not be 'null'!
* @param remove Set to true if all visible gate blocks shall be removed.
*/
public static void updateGateBlocks(final Gate gate, boolean remove) {
assert(gate != null);
Location gateLocation = gate.getLocation();
if (gate.getGateBlockLocations().isEmpty()) {
return;
}
ArrayList<Player> playersNearby = new ArrayList<>();
int searchRadius = Plugin.getPlugin().getConfig().getInt(confPlayerGateBlockUpdateRadiusKey);
for (Player p : Plugin.getPlugin().getServer().getOnlinePlayers()) {
if (p.getWorld() == gateLocation.getWorld() && p.getLocation().distance(gateLocation) < searchRadius) {
playersNearby.add(p);
}
}
boolean isVisible = gate.isOpen() && !remove;
for (Player p : playersNearby) {
sendGateBlockChanges(gate, isVisible, p);
}
}
private static void scheduleDelighting(final Player player, final Set<Gate> gates) {
Plugin plugin = Plugin.getPlugin();
long highlightDuration = 20 * plugin.getConfig().getLong(confHighlightDurationKey);
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
dehighlightGatesFrames(player, gates);
}
}, highlightDuration);
}
private static void dehighlightGatesFrames(final Player player, final Set<Gate> gates) {
for (Gate g : gates) {
Set<Block> frameBlocks = g.getGateFrameBlocks();
for (Block b : frameBlocks) {
player.sendBlockChange(b.getLocation(), b.getType(), (byte) 0);
}
}
}
private static void sendGateBlockChanges(final Gate gate, boolean isVisible, final Player p) {
byte data;
Material material;
if (isVisible) {
GateMaterial gm = gate.getMaterial();
data = gm.getData(gate.getDirection());
material = gm.getMaterial();
} else {
data = 0b0;
material = Material.AIR;
}
for (Location l : gate.getGateBlockLocations()) {
if (l.getBlock().getType() == Material.AIR) {
p.sendBlockChange(l, material, data);
}
}
}
}

View File

@ -1,83 +0,0 @@
package de.craftinc.gates.util;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.BlockFace;
import de.craftinc.gates.Gate;
public class GateUtil
{
public static Gate closestGate(Location location)
{
Gate gate = null;
double minmalDist = Double.MAX_VALUE;
for (Gate g : Gate.getAll()) {
if (!g.getLocation().getWorld().equals(location.getWorld()))
{
continue;
}
double tempDist = g.getLocation().distance(location);
if (tempDist < minmalDist)
{
gate = g;
minmalDist = tempDist;
}
}
return gate;
}
public static Gate getGateAtPlayerLocation(Location location)
{
Gate gate = null;
World playerWorld = location.getWorld();
// players are sometime stuck into the ground
Location locationUp = location.getBlock().getRelative(BlockFace.UP).getLocation();
for (Gate g : Gate.getAll())
{
if (gate != null)
{
break;
}
// Check if the gate is open and useable
World gateWorld = g.getLocation().getWorld();
if (!g.isOpen() || !gateWorld.equals(playerWorld))
{
continue;
}
// Check if the location matches
for (Location l: g.getGateBlockLocations()) {
if (LocationUtil.locationsAreAtSamePositions(l, location) || LocationUtil.locationsAreAtSamePositions(l, locationUp))
{
// Check if the gate is still valid
try {
g.validate();
gate = g;
break;
}
catch (Exception e2) {
break; // do nothing - gate got closed
}
}
}
}
return gate;
}
}

View File

@ -1,105 +0,0 @@
package de.craftinc.gates.util;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Location;
import org.bukkit.World;
import de.craftinc.gates.Plugin;
/**
* NOTE: We do not care about yaw and pitch for gate locations. So we won't serialize them.
*/
public class LocationUtil
{
protected static String worldKey = "world";
protected static String xKey = "x";
protected static String yKey = "y";
protected static String zKey = "z";
protected static World getWorld(String name) throws Exception
{
World world = Plugin.instance.getServer().getWorld(name);
if (world == null) {
throw new Exception("World '" + name + "' does not exists anymore! Cannot get instance!");
}
return world;
}
public static Map<String, Object> serializeLocation(Location l)
{
if (l == null) {
return null;
}
Map<String, Object> serializedLocation = new HashMap<String, Object>();
serializedLocation.put(worldKey, l.getWorld().getName());
serializedLocation.put(xKey, l.getX());
serializedLocation.put(yKey, l.getY());
serializedLocation.put(zKey, l.getZ());
return serializedLocation;
}
public static Location deserializeLocation(Map<String, Object> map) throws Exception
{
if (map == null) {
return null;
}
World w = getWorld((String)map.get(worldKey));
// verbose loading of coordinates (they might be Double or Integer)
Object objX = map.get(xKey);
Object objY = map.get(yKey);
Object objZ = map.get(zKey);
double x,y,z;
if (objX instanceof Integer)
x = (double)(Integer)objX;
else
x = (Double)objX;
if (objY instanceof Integer)
y = (double)(Integer)objY;
else
y = (Double)objY;
if (objZ instanceof Integer)
z = (double)(Integer)objZ;
else
z = (Double)objZ;
return new Location(w, x, y, z);
}
public static boolean locationsAreAtSamePositions(final Location l1, final Location l2)
{
if (l1.getWorld() != l2.getWorld() && (l1.getWorld() == null || !l1.getWorld().equals(l2.getWorld()))) {
return false;
}
if (new Double(l1.getX()).longValue() != new Double(l2.getX()).longValue()) {
return false;
}
if (new Double(l1.getY()).longValue() != new Double(l2.getY()).longValue()) {
return false;
}
if (new Double(l1.getZ()).longValue() != new Double(l2.getZ()).longValue()) {
return false;
}
return true;
}
}

View File

@ -1,68 +1,65 @@
/* Craft Inc. Gates
Copyright (C) 2011-2013 Craft Inc. Gates Team (see AUTHORS.txt)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program (LGPLv3). If not, see <http://www.gnu.org/licenses/>.
*/
package de.craftinc.gates.util; package de.craftinc.gates.util;
import org.bukkit.ChatColor;
import java.util.List; import java.util.List;
import org.bukkit.ChatColor; public class TextUtil {
import org.bukkit.Material;
public class TextUtil public static String titleSize(String str) {
{ String center = ".[ " + ChatColor.YELLOW + str + ChatColor.GOLD + " ].";
public static String titleize(String str)
{ if (center.length() >= 60) {
String line = ChatColor.GOLD + repeat("_", 60); return ChatColor.GOLD + center;
String center = ".[ " + ChatColor.YELLOW + str + ChatColor.GOLD + " ]."; } else {
int pivot = line.length() / 2; String line = ChatColor.GOLD + repeat("_", 60);
int eatLeft = center.length() / 2;
int eatRight = center.length() - eatLeft; int pivot = line.length() / 2;
int eatLeft = center.length() / 2;
return line.substring(0, pivot - eatLeft) + center + line.substring(pivot + eatRight); int eatRight = center.length() - eatLeft;
}
return line.substring(0, pivot - eatLeft) + center + line.substring(pivot + eatRight);
}
public static String repeat(String s, int times) }
{
if (times <= 0)
return ""; private static String repeat(String s, int times) {
if (times <= 0)
return s + repeat(s, times-1); return "";
}
return s + repeat(s, times - 1);
}
/**
* Joins all emements of list into a single string, sperating the original strings with glue. /**
*/ * Joins all elements of list into a single string, separating the original strings with glue.
public static String implode(List<String> list, String glue) */
{ public static String implode(List<String> list, String glue) {
if (list.size() == 0) { if (list.size() == 0) {
return ""; return "";
} }
String ret = list.get(0); String ret = list.get(0);
for (int i=1; i<list.size(); i++) { for (int i = 1; i < list.size(); i++) {
ret += glue + list.get(i); ret += glue + list.get(i);
} }
return ret; return ret;
} }
/**
* Joins all emements of list into a single string.
*/
public static String implode(List<String> list) {
return implode(list, "");
}
public static String getMaterialName(Material material)
{
String ret = material.toString();
ret = ret.replace('_', ' ');
ret = ret.toLowerCase();
return ret.substring(0, 1).toUpperCase() + ret.substring(1);
}
} }