162 Commits

Author SHA1 Message Date
e2903514fe read me updated. 2014-02-07 10:54:45 +01:00
44e86059de Bumped version to 2.4.0 2014-02-05 20:48:58 +01:00
fe0946117e Read me updated. 2014-02-05 20:48:37 +01:00
43dd934f48 Docs updated. 2014-02-05 20:43:08 +01:00
b37f1000ab Merge branch 'development' of github.com:craftinc/craftinc-gates into development 2014-02-05 20:36:34 +01:00
c7a423ff20 Display information about allowed vehicles when executing the info command. 2014-02-05 20:36:23 +01:00
b676af278d Display a not allowed while riding message. 2014-02-05 20:23:59 +01:00
a579209037 Do call the exit changed method of the gates manager. 2014-02-05 20:16:16 +01:00
ca74b2e3ed Removed invalid to do notes. 2014-02-05 20:15:56 +01:00
6924e36249 Added soft-depend for multi-world plugins 2014-01-27 09:51:57 +01:00
f8f31640ef Added gate change listener interface used for dynmap. 2014-01-26 14:29:28 +01:00
c80b0f0f68 Fix not persistent allow/deny riding flag. 2014-01-19 21:01:28 +01:00
2bd8b0ff03 Fixed broken migration for old storage versions. 2014-01-06 17:28:59 +01:00
a613b1933a Send messages to players when executing allow/deny riding commands. 2014-01-06 17:21:43 +01:00
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
0c13d0d3e3 Fix for missing clone of pig attributes. 2013-12-29 09:51:26 +01:00
29592823b6 Bumped version to 2.4.0-DEV 2013-12-29 09:50:14 +01:00
56c6af02b1 Keep velocity when teleporing boats and minecarts. This commit completes issue #10 2013-12-28 16:43:18 +01:00
8b873a6d60 Added support for vehicles. 2013-12-28 15:11:12 +01:00
e36519c246 gitignore updated. 2013-12-28 15:10:30 +01:00
125d327a0d Updated bukkit dependency. 2013-12-28 10:25:09 +01:00
6c8658f7c5 Fixed typo. Did some cleanup. 2013-12-28 10:24:55 +01:00
14041f8cd7 Updated bukkit dependency to 1.7.2-R0.1-SNAPSHOT. 2013-12-08 16:21:18 +01:00
bb4a41e782 Readme updated. #2 2013-11-26 09:21:01 +01:00
82df684c22 Readme updated. 2013-11-26 09:16:14 +01:00
7f89917e81 Updated version to 2.3.0. 2013-11-24 12:55:47 +01:00
a1cb0102f8 Changed the executing phase of deployment script. 2013-11-23 15:31:27 +01:00
5af520f8ea include mcstats in jar file when packaging with maven 2013-11-23 15:11:13 +01:00
28cacfdb19 Updated the changelog and other documents for the upcoming 2.3 release. 2013-11-16 17:54:33 +01:00
757d6b5a48 readme updated. 2013-11-16 15:40:53 +01:00
056b8896a6 Updated bukkit depency. 2013-11-16 15:40:45 +01:00
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
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
260cabc509 Small typo fix. 2013-08-07 16:40:59 +02:00
0b29936958 Changed some text getting displayed while executing the info command. 2013-07-27 12:03:38 +02:00
efc30d0ae0 Added the nearby command. Issue #12 2013-07-24 10:39:37 +02:00
f4111fb34f Added a URL and license to the pom file. 2013-07-21 19:29:12 +02:00
37bce23e3d Updated a description inside the plugin.yml. 2013-07-18 12:09:50 +02:00
d5ff63c163 Added Plugin Metrics. 2013-07-16 12:09:20 +02:00
e60c735153 Removed the .settings folder. 2013-07-16 12:08:24 +02:00
013fad2b95 Added a license header to the exitopen command class. 2013-07-11 22:35:55 +02:00
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
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
54545a9ee1 Updated the change log. 2013-07-10 22:14:55 +02:00
560bbf0394 Updated the pom file for version 2.2.1 2013-07-10 22:02:19 +02:00
2150cc66d0 Changed the event priority of the player teleport listener to MONITOR. 2013-07-10 22:02:05 +02:00
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
577531db5e Updated the pom file for version 2.2.0 2013-07-06 17:14:11 +02:00
3739ee6c5a Added a toString method to the SimpleLocation class. 2013-07-06 17:13:46 +02:00
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
02fd7a4916 Added missing whitespace character. 2013-07-06 15:42:29 +02:00
e21089d8c7 Removed a newline character. 2013-07-04 12:47:28 +02:00
fc488e7f31 Remove portal blocks at the old location of a gate when setting a new location. 2013-07-04 10:19:57 +02:00
e8f23078f1 Check for case insensitivity while loading gates from disk. 2013-07-04 10:08:59 +02:00
9ec2b91181 Typo fix. 2013-07-01 20:46:23 +02:00
478095190a Added newlines toe the change log. 2013-07-01 13:50:02 +02:00
17942caa73 README.md: fixed some typos 2013-07-01 13:30:09 +02:00
d0c23b581a Fixed some typos inside the readme file. 2013-06-30 13:36:56 +02:00
6884f43e50 Documentation and readme updated. 2013-06-29 12:19:12 +02:00
e84130a8fe Better handling for players entering a gate with their head only. 2013-06-26 12:28:30 +02:00
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
aeae14e2a0 Added a option for saving gates after every change. 2013-06-24 09:50:49 +02:00
36be95d0f5 Gate: Added final statement to arguments. Better handling for case insensitivity. 2013-06-24 09:44:44 +02:00
ed4dd5711e Make gate ids case insensitive. 2013-06-23 20:14:19 +02:00
437296262c Cleanup 2013-06-23 20:13:53 +02:00
ec2caaad97 Removed debug prints. 2013-06-23 19:55:03 +02:00
81daa83f44 code cleanup. 2013-06-23 19:26:13 +02:00
0695b3e202 Improved error messages when setting a gate location. 2013-06-23 19:09:20 +02:00
6df27c14a0 Bugfix: portal blocks don't get set when unhiding a gate. 2013-06-23 19:04:07 +02:00
a16d847234 Better print out for creating gates a invalid locations. 2013-06-23 18:48:18 +02:00
d24f0b8fd1 Bugfix: new gates do not work when opening them. 2013-06-23 18:47:17 +02:00
ea52e4d87e Also check for the players head locations when trying to teleport the player. 2013-06-23 18:46:03 +02:00
f4495240a5 Remove and add gates to the gate attributes. 2013-06-23 18:43:22 +02:00
09b9c65ef6 Added some prints for debugging. 2013-06-23 18:07:18 +02:00
afe693d491 Bugfix: remove portal blocks when deleting a gate. 2013-06-23 17:27:57 +02:00
d4f33a1885 Do not cast to Double. Rather use Number. 2013-06-23 17:14:51 +02:00
b50a2b27d3 Bugfix: do not let the location command fail if previous location was invalid. 2013-06-23 17:09:39 +02:00
e88e03ed42 Removed a debug print. 2013-06-23 17:08:44 +02:00
53e2be6be7 Bugfix: Only check distance between players in the same world! 2013-06-23 15:32:33 +02:00
d29ad9a474 Removed some debug prints. 2013-06-21 21:36:47 +02:00
4f89e20e6f Print reason when closing gate on save. 2013-06-20 23:07:10 +02:00
563bdfe2fd Updated the change log. 2013-06-20 22:36:03 +02:00
931cd1a520 Updated the build scripts. Bumped version to 2.2.0-beta. 2013-06-20 22:35:46 +02:00
b64f41ce0c Do not log "enabled" when gate storage file is corrupted. 2013-06-20 19:58:34 +02:00
1e9b9905a5 Disable the plugin if storage migration is not possible. 2013-06-20 19:19:00 +02:00
d28bedb78e Better handling for invalid gate storage files. 2013-06-19 17:18:35 +02:00
e9c4583c3d Updated command classes to use better shortcut commands. (Issue #21) 2013-06-19 17:17:56 +02:00
7a8e61104a Disable the plugin if the gate storage file is corrupted. 2013-06-19 14:25:31 +02:00
c764850ded Declared many arguments as final inside the GatesManager class. 2013-06-19 14:08:27 +02:00
f939e27464 Added a delayed block changes sending method. 2013-06-19 14:03:50 +02:00
ecd219fb2d Added parameter checks and final attributes to the FloodUtil class. 2013-06-19 13:42:16 +02:00
99be2905be Added checks for broken gate frame blocks. 2013-06-18 19:53:04 +02:00
9e36cf189b Added a configuration file. Made various classes read from the configuration. 2013-06-17 14:32:49 +02:00
78283a4f34 Send block changes on command execution. 2013-06-15 15:33:01 +02:00
1d08c79cff Check for non existing gate list while loading gates from disk. 2013-06-15 13:33:19 +02:00
cb0dec8b83 More distant portal blocks now get send to players. 2013-06-12 21:58:01 +02:00
1968ccaaeb Added an authors file. Added a license section the each source file. 2013-06-05 13:00:29 +02:00
d23a9b7650 Added basic gate block sending mechanism. 2013-06-03 19:14:56 +02:00
e5ef266f04 Refactoring: created new packages. 2013-06-03 16:37:20 +02:00
724e05e0a4 code and comment cleanup. 2013-06-03 16:19:51 +02:00
b18df58870 Refactoring of the LocationUtil class. 2013-06-03 16:09:26 +02:00
7119c185e7 Version bump to 2.2.0-DEV 2013-06-01 15:07:03 +02:00
c740a5b111 Fixed a bug where gates did not work after chaining it's location. 2013-06-01 15:02:22 +02:00
8bee74df89 Code cleanup. 2013-06-01 15:01:59 +02:00
b383ff89c6 Cleanup 2013-06-01 14:50:39 +02:00
fec999541e Removed the ChunkLoadListener. 2013-06-01 14:45:47 +02:00
2ed611d995 Only teleport players once if they got pending teleport requests. 2013-06-01 12:43:39 +02:00
faabb2f9db Testing code for not working chunk load listener. 2013-06-01 12:29:28 +02:00
e6e6273147 Made chunk load listener handle multiple teleport requests with the same destination chunk. 2013-06-01 11:32:18 +02:00
093778f2fb Added missing TeleportRequest class. 2013-05-26 14:52:15 +02:00
a5b34458c4 Make sure chunks are loaded before teleporting players. 2013-05-26 14:52:04 +02:00
30d15c141e Refactored the Gate class: removed the fill and empty methods. 2013-05-26 14:03:18 +02:00
3cac4e70cc Allow bigger portals. Portals cannot be made of portal blocks anymore. 2013-05-26 13:08:50 +02:00
95446f1371 Throw an exception when the gates got stored with a newer version. 2013-05-26 13:03:22 +02:00
8e860e90c6 code style. 2013-05-26 12:36:43 +02:00
d9194c7497 Added a storage migration class. 2013-05-26 12:36:25 +02:00
c3a24a940f Don't print block locations inside the info command. #2 2013-05-19 12:04:03 +02:00
c62fb32e90 Don't print block locations inside the info command. 2013-05-19 12:03:45 +02:00
580fda0273 Don't teleport if gates are closed. 2013-05-19 12:01:55 +02:00
252292819f Removed an unused method. 2013-05-19 12:01:34 +02:00
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
12fde472a2 Fixed a typo. 2013-05-19 12:00:07 +02:00
be3c541845 code style. 2013-05-19 11:59:47 +02:00
6bd53a3fe6 Fixed typos. 2013-05-19 10:39:23 +02:00
a9be1eaa51 Updated the test-deployment script. Keep the version inside the filename. 2013-05-19 10:38:48 +02:00
dd492a7327 updated the test-deployment script. 2013-05-19 10:06:27 +02:00
0230314c7e Added a little bit more logging. 2013-05-19 10:05:21 +02:00
768d385915 Renamed PluginPlayerListener to PlayerMoveListener 2013-05-18 19:56:10 +02:00
232305a871 Added some checks for null values to the GatesManager class. 2013-05-18 19:55:20 +02:00
00573c2763 Added some documentation to the Gate class. 2013-05-18 19:54:43 +02:00
f1d623df60 Fixed a typo. 2013-05-18 19:54:17 +02:00
040377cb36 Refactoring and code cleanup. 2013-05-18 11:26:45 +02:00
e9027900ce Refactored the BaseCommand class. 2013-05-18 11:11:10 +02:00
34b1c7e0ce Removed the 'h' shortcut. 2013-05-17 21:58:05 +02:00
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
0e13f60122 Fixer a typo. 2013-05-17 21:28:56 +02:00
f2bfe27eba Removed debug print. 2013-05-17 21:24:57 +02:00
7f8b8eee0f updated pom.xml to version 2.1.2 2013-05-17 21:14:36 +02:00
e0b30135cc Removed duplicate log message. 2013-05-17 21:14:19 +02:00
1056fbf969 updated pom.xml 2013-05-17 21:10:34 +02:00
916dc1b3a1 Updated changelog. 2013-05-17 21:05:36 +02:00
4b7fff2277 Fixed some typos 2013-05-17 20:53:36 +02:00
ed2683affc Fixed issue #18. Gates with 'null' as location did cause exceptions at many locations. 2013-05-17 20:13:49 +02:00
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
67c8a15e46 Merge branch 'development' of github.com:craftinc/craftinc-gates into development 2013-05-16 09:53:29 +02:00
a984f3a3ea Updated README.md 2013-05-16 09:53:24 +02:00
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
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
e30b82b74f added bukkit-testserver to gitignore
scripts for automatic bukkit-testserver handling
2013-05-13 17:33:27 +02:00
acf4c9002c updated pom.xml 2013-05-13 17:32:50 +02:00
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
8c6718d13f Removed unused imports. 2013-04-09 09:11:32 +02:00
6a34d44f20 Updated change log and plugin.yml. 2013-04-09 09:11:22 +02:00
b196c53335 Display messages about disallowed usage of gates less frequent. 2013-04-08 21:32:15 +02:00
d54fd7f72e Removed some debug code. 2013-04-08 21:09:15 +02:00
cede47deab Rewrite of the list command. 2013-04-08 21:08:08 +02:00
1ef178f6a0 Updated class path. (CraftBukkit 1.5.1 R0.1) 2013-04-07 19:33:07 +02:00
802f8c07e3 Merge branch 'master' of github.com:craftinc/craftinc-gates into development 2013-04-06 12:08:21 +02:00
a8a95af497 Further refactoring of the list command. 2013-04-06 12:08:09 +02:00
0af3631693 Removed unused imports. 2013-04-06 12:07:57 +02:00
4d40b140fa Start work on refactoring the list command. 2013-04-05 21:51:18 +02:00
8830355216 Updated the change log. 2013-03-26 20:59:18 +01:00
64 changed files with 4092 additions and 1652 deletions

View File

@ -1,12 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<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="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"/>
</classpath>

6
.gitignore vendored
View File

@ -27,4 +27,8 @@ target/
profile
# 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.
The hightlights are: __It is so darn easy to use!__ and __The gates can look any way you like__
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_.
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!
Thought first you should take a look at the demonstration oloflarsson and karibu6 created:
__[http://www.youtube.com/watch?v=L4hyqTpeEaA](http://www.youtube.com/watch?v=L4hyqTpeEaA)__
* Dynmap integration
* Gates with and without frames
* Gates consisting of portal blocks and gates made of air (so called hidden gates)
* 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?__
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?__
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.
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!
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.
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]__
Closes a gate to prevent players from using it.
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.
* __/gate create,new [id]__
Creates a gate at your current location.
To hide a gate simply call __/gate hide [id]__. Now that gate wont be made of purple portal blocks while open.
* __/gate delete,del,remove,rm [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 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.
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.
## 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__
Gives access to info and list commands.
## Craft Inc. ##
Check out our __[Craft Inc. Minecraft Server](http://www.craftinc.de)__. Everyone is welcome!
* __craftincgates.use__
Allows you to travel via gates.
Also check out our other great plugins:
* __craftincgates.manage__
Gives access to commands manipulating gates.
* [__Craft Inc. BorderProtection__](http://dev.bukkit.org/bukkit-mods/craftinc-borderprotection/)
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/)__
2. Put the downloaded _CraftIncGates.jar_ in the plugins folder.
3. Start or reload the server.
* __Craft Inc. Scarecrow__
coming soon!
## 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.
## License
This project has a LGPL license just like the Bukkit project.
## Legal Information ##
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 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.
* Fixed a bug where players in creative mode would not be teleported correctly.
* 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
version: 2.1.0
name: ${project.name}
version: ${project.version}
description: A plugin to create gates for fast traveling.
softdepend: [Vault]
softdepend: [Vault, Multiverse-Core, MultiWorld, RoyalCommands]
author: tomco, s1m0ne
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
database: false
@ -16,7 +16,7 @@ commands:
permissions:
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:
craftincgates.info: true
craftincgates.use: true

124
pom.xml
View File

@ -4,50 +4,134 @@
<modelVersion>4.0.0</modelVersion>
<groupId>de.craftinc</groupId>
<artifactId>CraftIncGates</artifactId>
<name>Craft Inc. Gates</name>
<url>http://dev.bukkit.org/bukkit-plugins/craftinc-gates/</url>
<packaging>jar</packaging>
<version>1.1.1</version>
<version>2.4.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>RELEASE</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.milkbowl.vault</groupId>
<artifactId>Vault</artifactId>
<version>1.2.23-SNAPSHOT</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
</dependencies>
<!-- License -->
<licenses>
<license>
<name>GNU Lesser General Public License Version 3</name>
<url>https://www.gnu.org/licenses/lgpl-3.0-standalone.html</url>
<distribution>repo</distribution>
</license>
</licenses>
<build>
<directory>target</directory>
<outputDirectory>target/classes</outputDirectory>
<finalName>${project.artifactId}</finalName>
<finalName>${project.name} ${project.version}</finalName>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>resources</directory>
<filtering>true</filtering>
</resource>
</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>
<dependencies>
<dependency>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.7.2-R0.2-SNAPSHOT</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>net.milkbowl.vault</groupId>
<artifactId>Vault</artifactId>
<version>1.2.27-SNAPSHOT</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.mcstats.bukkit</groupId>
<artifactId>metrics</artifactId>
<version>R8-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<repositories>
<repository>
<id>bukkit-repo</id>
<url>http://repo.bukkit.org/content/groups/public</url>
</repository>
<repository>
<id>vault-repo</id>
<url>http://ci.herocraftonline.com/plugin/repository/everything</url>
</repository>
<repository>
<id>Plugin Metrics</id>
<url>http://repo.mcstats.org/content/repositories/public</url>
</repository>
</repositories>
</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,60 +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;
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 de.craftinc.gates.util.ConfigurationUtil;
import de.craftinc.gates.util.FloodUtil;
import de.craftinc.gates.persistence.LocationUtil;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import de.craftinc.gates.util.LocationUtil;
import java.util.*;
/**
* Adds persistence and serialization to the base gate class.
*/
public class Gate extends BaseGate implements ConfigurationSerializable
public class Gate implements ConfigurationSerializable
{
/*
* 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 Set<Block> gateFrameBlocks = new HashSet<Block>();
protected Location exit;
protected boolean isHidden = false;
protected boolean isOpen = false;
protected boolean allowsVehicles = true;
protected String id;
protected static Map<String, Gate> instances = new HashMap<String, Gate>();
/*
* CONSTRUCTORS
*/
public Gate(String id) throws Exception
/**
* 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);
}
/*
* 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;
setId(id);
}
@ -64,6 +58,214 @@ public class Gate extends BaseGate implements ConfigurationSerializable
}
/**
*
* @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<Location>();
this.gateFrameBlocks = new HashSet<Block>();
}
}
/**
*
* @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 isHidden()
{
return isHidden;
}
public void setHidden(boolean isHidden) throws Exception
{
this.isHidden = isHidden;
this.validate();
}
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;
}
protected void findPortalBlocks()
{
gateBlockLocations = new HashSet<Location>();
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<Location>();
this.gateFrameBlocks = new HashSet<Block>();
throw new Exception("Gate got closed. It has no location.");
}
if (exit == null) {
isOpen = false;
this.gateBlockLocations = new HashSet<Location>();
this.gateFrameBlocks = new HashSet<Block>();
throw new Exception("Gate got closed. It has no exit.");
}
if (gateBlockLocations.size() == 0) {
isOpen = false;
this.gateBlockLocations = new HashSet<Location>();
this.gateFrameBlocks = new HashSet<Block>();
throw new Exception("Gate got closed. The frame is missing or broken. (no gate blocks)");
}
if (!isHidden() && Plugin.getPlugin().getConfig().getBoolean(ConfigurationUtil.confCheckForBrokenGateFramesKey)) {
for (Block b : gateFrameBlocks) {
if (b.getType() == Material.AIR) {
isOpen = false;
this.gateBlockLocations = new HashSet<Location>();
this.gateFrameBlocks = new HashSet<Block>();
throw new Exception("Gate got closed. The frame is missing or broken. (missing frame block(s))");
}
}
}
}
/*
* INTERFACE: ConfigurationSerializable
*/
@ -77,13 +279,15 @@ public class Gate extends BaseGate implements ConfigurationSerializable
static protected String locationPitchKey = "locationPitch";
static protected String exitYawKey = "exitYaw";
static protected String exitPitchKey = "exitPitch";
static protected String allowsVehiclesKey = "allowsVehiclesKey";
@SuppressWarnings("unchecked")
public Gate(Map<String, Object> map)
public Gate(Map<String, Object> map)
{
try {
id = map.get(idKey).toString();
try {
id = map.get(idKey).toString().toLowerCase();
isHidden = (Boolean)map.get(isHiddenKey);
isOpen = (Boolean)map.get(isOpenKey);
@ -91,14 +295,18 @@ public class Gate extends BaseGate implements ConfigurationSerializable
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());
exit.setPitch(((Number)map.get(exitPitchKey)).floatValue());
exit.setYaw(((Number)map.get(exitYawKey)).floatValue());
}
if (map.containsKey(locationPitchKey)) {
location.setPitch(((Double)map.get(locationPitchKey)).floatValue());
location.setYaw(((Double)map.get(locationYawKey)).floatValue());
location.setPitch(((Number)map.get(locationPitchKey)).floatValue());
location.setYaw(((Number)map.get(locationYawKey)).floatValue());
}
if (map.containsKey(allowsVehiclesKey)) {
allowsVehicles = (Boolean)map.get(allowsVehiclesKey);
}
gateBlockLocations = new HashSet<Location>();
List<Map<String, Object>> serializedGateBlocks = (List<Map<String, Object>>)map.get(gateBlocksKey);
@ -106,29 +314,27 @@ public class Gate extends BaseGate implements ConfigurationSerializable
for (Map<String, Object> sgb : serializedGateBlocks) {
gateBlockLocations.add(LocationUtil.deserializeLocation(sgb));
}
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.instance.storeInvalidGate(map);
return;
Plugin.getPlugin().getGatesManager().storeInvalidGate(map);
}
instances.put(id, this);
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()
{
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);
@ -136,14 +342,17 @@ public class Gate extends BaseGate implements ConfigurationSerializable
retVal.put(exitKey, LocationUtil.serializeLocation(exit));
retVal.put(isHiddenKey, isHidden);
retVal.put(isOpenKey, isOpen);
retVal.put(allowsVehiclesKey, allowsVehicles);
if (exit != null) {
retVal.put(exitPitchKey, exit.getPitch());
retVal.put(exitYawKey, exit.getYaw());
}
retVal.put(locationPitchKey, location.getPitch());
retVal.put(locationYawKey, location.getYaw());
if (location != null) {
retVal.put(locationPitchKey, location.getPitch());
retVal.put(locationYawKey, location.getYaw());
}
List<Map<String, Object>> serializedGateBlocks = new ArrayList<Map<String, Object>>();
@ -155,58 +364,4 @@ public class Gate extends BaseGate implements ConfigurationSerializable
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

@ -0,0 +1,31 @@
/* Craft Inc. Gates
Copyright (C) 2011-2014 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;
import java.util.Map;
public interface GateChangeListener
{
public static final String newGate = "GateChangeListener-newGate"; // value will be null
public static final String removedGate = "GateChangeListener-removedGate"; // value will be null
public static final String changedID = "GateChangeListener-changedID"; // value will be the old ID
public static final String changedLocation = "GateChangeListener-changedLocation"; // value will the old location
public static final String changedExit = "GateChangeListener-changedExit"; // value will be the old exit
public void gateChangedHandler(final Gate g, final Map<String, Object>changeSet);
}

View File

@ -0,0 +1,599 @@
/* 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;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
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.util.SimpleChunk;
import de.craftinc.gates.util.SimpleLocation;
public class GatesManager
{
protected File gatesConfigFile;
protected FileConfiguration gatesConfig;
protected static final String gatesPath = "gates"; // path to gates inside the yaml file
protected static final String storageVersionPath = "version";
protected static final int storageVersion = 2;
protected int chunkRadius;
protected Map<String, Gate> gatesById;
protected Map<SimpleChunk, Set<Gate>> gatesByChunk;
protected Map<SimpleLocation, Gate> gatesByLocation;
protected Map<SimpleLocation, Gate> gatesByFrameLocation;
protected List<Gate> gates;
protected boolean storageFileIsInvalid = false;
protected Set<GateChangeListener> changeListeners = new HashSet<GateChangeListener>();
public void addGateChangeListener(GateChangeListener listener)
{
this.changeListeners.add(listener);
}
public void removeGateChangeListener(GateChangeListener listener)
{
this.changeListeners.remove(listener);
}
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;
}
public 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()
{
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<Gate>();
}
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;
}
protected int getChunkRadius()
{
if (this.chunkRadius == 0) {
this.chunkRadius = Plugin.getPlugin().getConfig().getInt(ConfigurationUtil.confPlayerGateBlockUpdateRadiusKey);
this.chunkRadius = this.chunkRadius >> 4;
}
return this.chunkRadius;
}
protected void fillGatesById()
{
gatesById = new HashMap<String, Gate>((int)(gates.size() * 1.25));
for (Gate g : gates) {
this.addGateWithId(g);
}
}
protected void fillGatesByChunk()
{
HashSet<SimpleChunk> chunksUsedByGates = new HashSet<SimpleChunk>();
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<SimpleChunk, Set<Gate>>((int)(chunksUsedByGates.size() * 1.25));
for (Gate g : gates) {
this.addGateByChunk(g);
}
}
protected void fillGatesByLocation()
{
Set<Location> gateBlocks = new HashSet<Location>();
for (Gate g : gates) {
for (Location l : g.getGateBlockLocations()) {
gateBlocks.add(l);
Location headLocation = new Location(l.getWorld(),
l.getX(),
l.getY()+1,
l.getZ());
gateBlocks.add(headLocation);
}
}
gatesByLocation = new HashMap<SimpleLocation, Gate>((int)(gateBlocks.size()*1.25));
for (Gate g : gates) {
this.addGateByLocations(g);
}
}
protected void fillGatesByFrameLocation()
{
int numFrameBlocks = 0;
for (Gate g : gates) {
numFrameBlocks += g.gateFrameBlocks.size();
}
gatesByFrameLocation = new HashMap<SimpleLocation, Gate>((int)(numFrameBlocks*1.25));
for (Gate g : gates) {
this.addGateByFrameLocations(g);
}
}
protected void removeGateById(final String id)
{
gatesById.remove(id);
}
protected void addGateWithId(final Gate g)
{
gatesById.put(g.getId(), g);
}
protected 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);
}
}
}
protected void removeGateByFrameLocation(final Set<Block> gateFrameBlocks)
{
if (gateFrameBlocks != null) {
for (Block block : gateFrameBlocks) {
SimpleLocation sl = new SimpleLocation(block.getLocation());
gatesByFrameLocation.remove(sl);
}
}
}
protected 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);
}
}
protected void addGateByFrameLocations(final Gate g)
{
for (Block block : g.getGateFrameBlocks()) {
SimpleLocation sl = new SimpleLocation(block.getLocation());
gatesByFrameLocation.put(sl, g);
}
}
protected 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);
}
}
}
}
}
protected 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<Gate>(); // 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);
Map<String, Object> changeSet = new HashMap<String, Object>();
changeSet.put(GateChangeListener.changedID, oldId);
for (GateChangeListener l : this.changeListeners) {
l.gateChangedHandler(g, changeSet);
}
}
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);
Map<String, Object> changeSet = new HashMap<String, Object>();
changeSet.put(GateChangeListener.changedLocation, oldLocation);
for (GateChangeListener l : this.changeListeners) {
l.gateChangedHandler(g, changeSet);
}
}
public void handleGateExitChange(final Gate g, final Location oldExit)
{
// nothing to do
Map<String, Object> changeSet = new HashMap<String, Object>();
changeSet.put(GateChangeListener.changedExit, oldExit);
for (GateChangeListener l : this.changeListeners) {
l.gateChangedHandler(g, changeSet);
}
}
public void handleNewGate(final Gate g)
{
this.gates.add(g);
this.addGateByChunk(g);
this.addGateByLocations(g);
this.addGateWithId(g);
this.addGateByFrameLocations(g);
Map<String, Object> changeSet = new HashMap<String, Object>();
changeSet.put(GateChangeListener.newGate, null);
for (GateChangeListener l : this.changeListeners) {
l.gateChangedHandler(g, changeSet);
}
}
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());
Map<String, Object> changeSet = new HashMap<String, Object>();
changeSet.put(GateChangeListener.removedGate, null);
for (GateChangeListener l : this.changeListeners) {
l.gateChangedHandler(g, changeSet);
}
}
public boolean gateExists(final String id)
{
return gatesById.containsKey(id.toLowerCase());
}
public List<Gate> allGates ()
{
return gates;
}
}

View File

@ -1,57 +1,62 @@
/* 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;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import de.craftinc.gates.listeners.*;
import de.craftinc.gates.util.ConfigurationUtil;
import net.milkbowl.vault.permission.Permission;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
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.plugin.PluginManager;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
import de.craftinc.gates.commands.*;
import de.craftinc.gates.listeners.PluginBlockListener;
import de.craftinc.gates.listeners.PluginPlayerListener;
import de.craftinc.gates.listeners.PluginPortalListener;
import org.mcstats.Metrics;
public class Plugin extends JavaPlugin
{
public static Plugin instance;
public static final String permissionInfo = "craftincgates.info";
public static final String permissionManage = "craftincgates.manage";
// public static final String permissionAll = "craftincgates.*";
public static final String permissionUse = "craftincgates.use";
public static Permission permission = null;
private static Plugin instance;
private static Permission permission;
public PluginPlayerListener playerListener = new PluginPlayerListener();
public PluginBlockListener blockListener = new PluginBlockListener();
public PluginPortalListener portalListener = new PluginPortalListener();
private File gatesConfigFile;
private FileConfiguration gatesConfig;
private String baseCommand;
private String gatesPath = "gates";
// Commands
public List<BaseCommand> commands = new ArrayList<BaseCommand>();
protected String baseCommand;
protected List<BaseCommand> commands = new ArrayList<BaseCommand>();
protected GatesManager gatesManager = new GatesManager();
protected PlayerMoveListener moveListener = new PlayerMoveListener();
protected PlayerTeleportListener teleportListener = new PlayerTeleportListener();
protected PlayerRespawnListener respawnListener = new PlayerRespawnListener();
protected PlayerChangedWorldListener worldChangeListener = new PlayerChangedWorldListener();
protected PlayerJoinListener joinListener = new PlayerJoinListener();
protected BlockBreakListener blockBreakListener = new BlockBreakListener();
public Plugin()
@ -60,14 +65,26 @@ public class Plugin extends JavaPlugin
}
public static Plugin getPlugin()
{
return instance;
}
public GatesManager getGatesManager()
{
return gatesManager;
}
@Override
public void onLoad()
{
ConfigurationSerialization.registerClass(Gate.class);
}
private void setupPermissions()
protected void setupPermissions()
{
if (getServer().getPluginManager().getPlugin("Vault") == null) {
return;
@ -91,7 +108,8 @@ public class Plugin extends JavaPlugin
public void onDisable()
{
// Save gates
saveGates();
gatesManager.saveGatesToDisk();
log("Disabled");
}
@ -99,49 +117,71 @@ public class Plugin extends JavaPlugin
@Override
public void onEnable()
{
// Setup Metrics
try {
Metrics metrics = new Metrics(this);
metrics.start();
}
catch (IOException e) {
log("Failed to start metrics!");
}
// Setup configuration
this.saveDefaultConfig();
// 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 CommandNew());
commands.add(new CommandRemove());
commands.add(new CommandLocation());
commands.add(new CommandExit());
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());
commands.add(new CommandHide());
commands.add(new CommandUnhide());
commands.add(new CommandExitOpen());
commands.add(new CommandNearby());
commands.add(new CommandAllowRiding());
commands.add(new CommandDenyRiding());
// Register events
PluginManager pm = this.getServer().getPluginManager();
pm.registerEvents(this.playerListener, this);
pm.registerEvents(this.blockListener, this);
pm.registerEvents(this.portalListener, this);
this.registerEventListeners();
// Load gates
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");
boolean success = gatesManager.loadGatesFromDisk();
if (success) {
log("Enabled");
}
else {
PluginManager pm = this.getServer().getPluginManager();
pm.disablePlugin(this);
}
}
protected 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);
if (getConfig().getBoolean(ConfigurationUtil.confCheckForBrokenGateFramesKey)) {
pm.registerEvents(this.blockBreakListener, this);
}
}
// -------------------------------------------- //
// Commands
@ -189,7 +229,8 @@ public class Plugin extends JavaPlugin
}
}
sender.sendMessage("Unknown gate-command \"" + commandName + "\". Try " + "/" + getBaseCommand() + " help");
sender.sendMessage(ChatColor.RED + "Unknown gate-command \"" + commandName + "\"." +
ChatColor.GREEN + " Try " + "/" + getBaseCommand() + " help");
}
@ -202,89 +243,13 @@ public class Plugin extends JavaPlugin
}
public static void log(Level level, String 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");
}
}
else {
fileWriter.write(value.toString() + "\n");
}
}
fileWriter.close();
}
catch (IOException e) {
log("ERROR: Could not save invalid gates to disk.");
e.printStackTrace();
}
public static Permission getPermission() {
return permission;
}
}

View File

@ -1,13 +1,31 @@
/* 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.ArrayList;
import java.util.List;
import de.craftinc.gates.util.ConfigurationUtil;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import de.craftinc.gates.Gate;
import de.craftinc.gates.GatesManager;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.TextUtil;
@ -52,8 +70,8 @@ public abstract class BaseCommand
this.perform();
if (this.shouldPersistToDisk) {
Plugin.instance.saveGates();
if (this.shouldPersistToDisk && Plugin.getPlugin().getConfig().getBoolean(ConfigurationUtil.confSaveOnChangesKey)) {
Plugin.getPlugin().getGatesManager().saveGatesToDisk();
}
}
@ -75,49 +93,37 @@ public abstract class BaseCommand
protected boolean validateCall()
{
boolean allParamtertersThere = parameters.size() >= requiredParameters.size();
boolean allParametersThere = 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))) {
if (this.hasGateParam && this.parameters.size() > 0 && this.setGateUsingParameter(this.parameters.get(0))) {
hasGateParameter = true;
}
boolean senderHasPermission = this.hasPermission();
boolean valid;
boolean valid = false;
if (this.senderMustBePlayer && !senderIsPlayer)
{
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;
}
else {
if (!allParametersThere) {
sendMessage(ChatColor.RED + "Some parameters are missing! " + ChatColor.AQUA + "Usage: " + this.getUsageTemplate(true));
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;
}
@ -125,13 +131,13 @@ public abstract class BaseCommand
protected boolean setGateUsingParameter(String param)
{
if (!Gate.exists(param))
{
GatesManager gateManager = Plugin.getPlugin().getGatesManager();
if (!gateManager.gateExists(param)) {
return false;
}
else
{
gate = Gate.get(param);
else {
gate = gateManager.getGateWithId(param);
return true;
}
}
@ -142,55 +148,41 @@ public abstract class BaseCommand
*/
protected boolean hasPermission()
{
if (Plugin.permission == null) // fallback <EFBFBD> use the standard bukkit permission system
{
if (Plugin.getPermission() == 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 <20> there is no information about the senders locations
return Plugin.permission.has(this.sender, this.requiredPermission);
if (!(this.sender instanceof Player)) {
// sender is no player - there is no information about the senders locations
return Plugin.getPermission().has(this.sender, this.requiredPermission);
}
Player p = (Player) this.sender;
boolean hasPermission = false;
if (this.requiredPermission.equals(Plugin.permissionInfo))
{
if (this.hasGateParam)
{
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 {
hasPermission = Plugin.getPermission().has(p.getWorld(), p.getName(), this.requiredPermission);
}
}
else if (this.requiredPermission.equals(Plugin.permissionUse) )
{
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);
else if (this.requiredPermission.equals(Plugin.permissionManage)) {
if (this.needsPermissionAtCurrentLocation && this.hasGateParam) {
boolean hasPersmissionAtCurrentLocation = Plugin.getPermission().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 if (this.needsPermissionAtCurrentLocation) {
hasPermission = Plugin.getPermission().has(p.getWorld(), p.getName(), this.requiredPermission);
}
else
{
else {
hasPermission = this.hasPermissionAtGateLocationAndExit(p);
}
}
@ -201,23 +193,12 @@ public abstract class BaseCommand
protected boolean hasPermissionAtGateLocationAndExit(Player p)
{
if (this.gate == null || p == null) // make sure we don't run into a nullpointer exception
{
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);
boolean permAtExit;
if (this.gate.getExit() == null)
{
permAtExit = true;
}
else
{
permAtExit = Plugin.permission.has(this.gate.getExit().getWorld(), p.getName(), this.requiredPermission);
}
boolean permAtLocation = this.gate.getLocation() == null || Plugin.getPermission().has(this.gate.getLocation().getWorld(), p.getName(), this.requiredPermission);
boolean permAtExit = this.gate.getExit() == null || Plugin.getPermission().has(this.gate.getExit().getWorld(), p.getName(), this.requiredPermission);
return permAtLocation & permAtExit;
}
@ -226,14 +207,15 @@ public abstract class BaseCommand
// -------------------------------------------- //
// Help and usage description
// -------------------------------------------- //
protected String getUsageTemplate(boolean withColor, boolean withDescription) {
protected String getUsageTemplate(boolean withColor, boolean withDescription)
{
String ret = "";
if (withColor) {
ret += ChatColor.AQUA;
}
ret += "/" + Plugin.instance.getBaseCommand() + " " + TextUtil.implode(this.getAliases(), ",")+" ";
ret += "/" + Plugin.getPlugin().getBaseCommand() + " " + TextUtil.implode(this.getAliases(), ",")+" ";
List<String> parts = new ArrayList<String>();
@ -263,11 +245,8 @@ public abstract class BaseCommand
return ret;
}
protected String getUseageTemplate(boolean withColor) {
protected String getUsageTemplate(boolean withColor)
{
return getUsageTemplate(withColor, false);
}
protected String getUseageTemplate() {
return getUseageTemplate(true);
}
}

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;
import org.bukkit.Location;
@ -9,8 +25,8 @@ public abstract class BaseLocationCommand extends BaseCommand
{
protected Location getValidPlayerLocation()
{
// The player might stand in a halfblock or a sign or whatever
// Therefore we load som extra locations and blocks
// The player might stand in a half block or a sign or whatever
// Therefore we load some extra locations and blocks
Block playerBlock = player.getLocation().getBlock();
Block upBlock = playerBlock.getRelative(BlockFace.UP);

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.Plugin;
import org.bukkit.ChatColor;
public class CommandAllowRiding extends BaseCommand
{
public CommandAllowRiding()
{
aliases.add("allowRiding");
aliases.add("ar");
requiredParameters.add("id");
helpDescription = "Allow players to travel while riding.";
requiredPermission = Plugin.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
senderMustBePlayer = false;
}
@Override
protected void perform()
{
gate.setAllowsVehicles(true);
sendMessage(ChatColor.GREEN + "Traveling while riding is now enabled for this gate.");
}
}

View File

@ -1,7 +1,24 @@
/* 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.util.GateBlockChangeSender;
import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin;
@ -33,6 +50,7 @@ public class CommandClose extends BaseCommand
try
{
gate.setOpen(false);
GateBlockChangeSender.updateGateBlocks(gate);
sendMessage(ChatColor.GREEN + "The gate was closed.");
}
catch(Exception e)
@ -41,8 +59,6 @@ public class CommandClose extends BaseCommand
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,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.Plugin;
import org.bukkit.ChatColor;
public class CommandDenyRiding extends BaseCommand
{
public CommandDenyRiding()
{
aliases.add("denyRiding");
aliases.add("dr");
requiredParameters.add("id");
helpDescription = "Deny players to travel while riding.";
requiredPermission = Plugin.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
senderMustBePlayer = false;
}
@Override
protected void perform()
{
gate.setAllowsVehicles(false);
sendMessage(ChatColor.GREEN + "Traveling while riding is now disabled for this gate.");
}
}

View File

@ -0,0 +1,64 @@
/* 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.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 = Plugin.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.");
Plugin.getPlugin().getGatesManager().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

@ -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.commands;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.GateBlockChangeSender;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import java.util.logging.Level;
public class CommandExitOpen extends BaseCommand
{
public CommandExitOpen()
{
aliases.add("exitopen");
aliases.add("eo");
requiredParameters.add("id");
helpDescription = "Change exit of location and open that gate afterwards.";
requiredPermission = Plugin.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.");
Plugin.getPlugin().getGatesManager().handleGateExitChange(gate, oldExit);
try {
boolean needsGateManagerUpdate = false;
if (gate.getGateBlockLocations().isEmpty()) {
needsGateManagerUpdate = true;
}
gate.setOpen(true);
GateBlockChangeSender.updateGateBlocks(gate);
if (needsGateManagerUpdate) {
Plugin.getPlugin().getGatesManager().handleGateLocationChange(gate, null, null, null);
}
sendMessage(ChatColor.GREEN + "The gate was opened.");
}
catch (Exception e) {
sendMessage(ChatColor.RED + e.getMessage());
}
}
catch (Exception e) {
GateBlockChangeSender.updateGateBlocks(gate);
sendMessage(ChatColor.RED + "Setting the exit for the gate failed! This gate is now closed! (See server log for more information.)");
Plugin.log(Level.WARNING, e.getMessage());
e.printStackTrace();
}
}
}

View File

@ -1,15 +1,28 @@
/* 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.Plugin;
import de.craftinc.gates.util.TextUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.bukkit.command.CommandSender;
import de.craftinc.gates.Gate;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.TextUtil;
public class CommandHelp extends BaseCommand
{
public static List<List<String>> helpPages;
@ -20,17 +33,19 @@ public class CommandHelp extends BaseCommand
List<String> allUsageStrings = new ArrayList<String>();
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 CommandNew().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandRemove().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandLocation().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandExit().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) );
allUsageStrings.add( new CommandHide().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandUnhide().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandExitOpen().getUsageTemplate(true, true) );
allUsageStrings.add( new CommandNearby().getUsageTemplate(true, true) );
Collections.sort(allUsageStrings);
@ -38,8 +53,7 @@ public class CommandHelp extends BaseCommand
// put 5 commands on one page
helpPages = new ArrayList<List<String>>();
while (!allUsageStrings.isEmpty())
{
while (!allUsageStrings.isEmpty()) {
int toIndex = allUsageStrings.size() >= 6 ? 5 : allUsageStrings.size();
List<String> currentHelpPage = new ArrayList<String>(allUsageStrings.subList(0, toIndex));
helpPages.add(currentHelpPage);
@ -52,7 +66,6 @@ public class CommandHelp extends BaseCommand
public CommandHelp()
{
aliases.add("help");
aliases.add("h");
aliases.add("?");
optionalParameters.add("page");
@ -65,35 +78,29 @@ public class CommandHelp extends BaseCommand
shouldPersistToDisk = false;
senderMustBePlayer = false;
}
public boolean hasPermission(CommandSender sender, Gate gate)
{
return true;
}
public void perform()
{
int page = 1;
public void perform()
{
int page;
if (parameters.size() > 0)
{
try
{
if (parameters.size() > 0) {
try {
page = Integer.parseInt(parameters.get(0));
}
catch (NumberFormatException e)
{
catch (NumberFormatException e) {
// wasn't an integer
page = 1;
}
}
else {
page = 1;
}
sendMessage(TextUtil.titleize("Craft Inc. Gates Help (" + page + "/" + helpPages.size() + ")"));
page -= 1;
if (page < 0 || page >= helpPages.size())
{
if (page < 0 || page >= helpPages.size()) {
sendMessage("This page does not exist");
return;
}

View File

@ -0,0 +1,59 @@
/* 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.util.GateBlockChangeSender;
import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin;
public class CommandHide extends BaseCommand
{
public CommandHide()
{
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);
GateBlockChangeSender.updateGateBlocks(gate);
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,10 +1,28 @@
/* 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.util.GateBlockChangeSender;
import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin;
import de.craftinc.gates.util.TextUtil;
import org.bukkit.entity.Player;
public class CommandInfo extends BaseCommand
@ -12,49 +30,88 @@ public class CommandInfo extends BaseCommand
public CommandInfo()
{
aliases.add("info");
aliases.add("details");
aliases.add("i");
aliases.add("d");
optionalParameters.add("id");
requiredParameters.add("id");
helpDescription = "Prints detailed informations about a certain gate.";
helpDescription = "Print detailed information about a certain or the closest gate.";
requiredPermission = Plugin.permissionInfo;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = false;
senderMustBePlayer = false;
hasGateParam = 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");
}
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.titleize("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 = Plugin.getPlugin().getGatesManager().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.titleize("Information about closest gate: '" + 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 + "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");
if (gate.getAllowsVehicles())
sendMessage(ChatColor.DARK_AQUA + "You can ride through this gate.");
if (this.sender instanceof Player) {
GateBlockChangeSender.temporaryHighlightGateFrame((Player)this.sender, this.gate);
}
}
}

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;
import java.util.ArrayList;
@ -15,6 +31,15 @@ import de.craftinc.gates.util.TextUtil;
public class CommandList extends BaseCommand
{
protected static final int linesPerPage = 10;
protected static final int charactersPerLine = 52; /* this is actually no true. the
font used by minecraft is not
monospace. but I don't think
there is a (easy) way for a
bukkit plugin to calculate
the drawing-size of a string.
*/
public CommandList()
{
aliases.add("list");
@ -32,42 +57,123 @@ public class CommandList extends BaseCommand
}
protected String intToTitleString(int i)
protected static List<String> linesOfGateIds(List<String> gates)
{
List<String> lines = new ArrayList<String>();
int index = 0;
List<String> gateIdsForCurrentLine = new ArrayList<String>();
int numCharactersInCurrentLine = 0;
while (index < gates.size()) {
String gateId = gates.get(index);
int gateIdLength = gateId.length() + 2; // actual length + comma + whitespace
// special case: very long gate id
if (gateIdLength > charactersPerLine && numCharactersInCurrentLine == 0) {
gateIdsForCurrentLine = new ArrayList<String>();
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++;
}
// gate fits into current line
else if ((numCharactersInCurrentLine + gateIdLength) <= charactersPerLine) {
gateIdsForCurrentLine.add(gateId);
numCharactersInCurrentLine += gateIdLength;
index++;
}
// the current gate does not fit on the
else {
lines.add(TextUtil.implode(gateIdsForCurrentLine, ", ") + ", ");
gateIdsForCurrentLine = new ArrayList<String>();
numCharactersInCurrentLine = 0;
}
}
lines.add(TextUtil.implode(gateIdsForCurrentLine, ", "));
return lines;
}
protected static String intToTitleString(int i, boolean addPreviousPageNote, boolean addNextPageNote)
{
String retVal = ChatColor.DARK_AQUA + "";
if ( i < 26 ) {
return ChatColor.DARK_AQUA + "" + (char)(i+65) + ":";
retVal += (char)(i+65);
}
else if ( i == 26 ) {
return ChatColor.DARK_AQUA + "0 - 9:";
retVal += "0-9";
}
else {
return ChatColor.DARK_AQUA + "!@#$:";
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 returning a collection of gates the player is allowed to see.
* Method for getting a collection of gates the player is allowed to see.
*/
protected Collection<Gate> getAllGates()
{
Collection<Gate> gates = Gate.getAll();
Collection<Gate> gates = Plugin.getPlugin().getGatesManager().allGates();
if (this.sender instanceof Player && Plugin.permission != null)
{
if (this.sender instanceof Player && Plugin.getPermission() != 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!
// create a copy since we cannot iterate over a collection while modifying it!
Collection<Gate> gatesCopy = new ArrayList<Gate>(gates);
for (Gate gate : gatesCopy) {
if (!Plugin.permission.has(gate.getLocation().getWorld(), p.getName(), this.requiredPermission))
{
if (gate.getLocation() != null) {
boolean permissionAtGateLocation = Plugin.getPermission().has(gate.getLocation().getWorld(), p.getName(), this.requiredPermission);
if (!permissionAtGateLocation) {
gates.remove(gate);
continue;
}
}
else if (gate.getExit() != null && !Plugin.permission.has(gate.getExit().getWorld(), p.getName(), this.requiredPermission))
{
gates.remove(gate);
if (gate.getExit() != null) {
boolean permissionAtGateExit = Plugin.getPermission().has(gate.getExit().getWorld(), p.getName(), this.requiredPermission);
if (!permissionAtGateExit) {
gates.remove(gate);
}
}
}
}
@ -76,30 +182,24 @@ public class CommandList extends BaseCommand
}
// pages start at 1
// will return null if requested page not availible
protected List<String> message(int page)
/**
* 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
*/
protected static List<List<String>> gatesSortedByName(Collection<Gate> allGates)
{
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
*/
// create the lists
List<List<String>> ids = new ArrayList<List<String>>();
for (int i=0; i<28; i++) {
ids.add(new ArrayList<String>());
}
for (Gate gate : gates) {
// put all gates into correct lists
for (Gate gate : allGates) {
String id = gate.getId();
int first = id.charAt(0);
@ -119,92 +219,97 @@ public class CommandList extends BaseCommand
ids.get(first).add(id);
}
// sort everything
for (int i=0; i<28; i++) {
Collections.sort(ids.get(i));
}
/* 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!)
*/
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.
*/
protected List<String> pagedGateIds()
{
Collection<Gate> gates = this.getAllGates();
int currentPage = 1;
int currentStartingCharList = 0;
boolean finishedCurrentIds = true;
if (gates.size() == 0) {
return null;
}
List<String> pageMessages = new ArrayList<String>();
List<List<String>> gatesSortedByName = gatesSortedByName(gates);
List<String> allPages = new ArrayList<String>();
int linesLeftOnPage = linesPerPage - 1;
String currentPageString = "";
while (currentStartingCharList < ids.size()) {
int linesLeftOnCurrentPage = 9;
for (int i=0; i<gatesSortedByName.size(); i++) {
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++;
}
List<String> currentGates = gatesSortedByName.get(i);
if(currentGates.isEmpty()) {
continue;
}
currentPage++;
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;
}
}
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;
// 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;
}
@ -215,7 +320,7 @@ public class CommandList extends BaseCommand
try {
page = new Integer(parameters.get(0));
}
catch (Exception e) { }
catch (Exception ignored) { }
return page;
}
@ -224,26 +329,23 @@ public class CommandList extends BaseCommand
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");
}
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;
}
else
{
sendMessage(messages);
if (page > allPages.size() || page < 1) {
sendMessage(ChatColor.RED + "The requested page is not availible");
return;
}
String message = TextUtil.titleize("List of all gates (" + page + "/" + allPages.size() + ")") + "\n";
message += allPages.get(page-1);
sendMessage(message);
}
}

View File

@ -0,0 +1,84 @@
/* 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.util.GateBlockChangeSender;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import de.craftinc.gates.Plugin;
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 = 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;
}
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 CommandOpen().getUsageTemplate(true, true));
}
finally {
Plugin.getPlugin().getGatesManager().handleGateLocationChange(gate, oldLocation, oldGateBlockLocations, oldFrameBlocks);
GateBlockChangeSender.updateGateBlocks(gate);
}
}
}

View File

@ -0,0 +1,53 @@
package de.craftinc.gates.commands;
import de.craftinc.gates.Gate;
import de.craftinc.gates.GatesManager;
import de.craftinc.gates.Plugin;
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 = Plugin.permissionInfo;
needsPermissionAtCurrentLocation = true;
shouldPersistToDisk = false;
senderMustBePlayer = true;
hasGateParam = false;
}
public void perform()
{
GatesManager manager = Plugin.getPlugin().getGatesManager();
Set<Gate> nearbyGates = manager.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<String>();
for (Gate g : nearbyGates) {
gateNames.add(g.getId());
}
player.sendMessage("Nearby gates: " + TextUtil.implode(gateNames, ", "));
}
}
}

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.commands;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import de.craftinc.gates.Gate;
import de.craftinc.gates.GatesManager;
import de.craftinc.gates.Plugin;
public class CommandNew extends BaseLocationCommand
{
public CommandNew()
{
aliases.add("new");
aliases.add("n");
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);
GatesManager gatesManager = Plugin.getPlugin().getGatesManager();
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, true));
}
gatesManager.handleNewGate(gate);
}
}

View File

@ -1,6 +1,23 @@
/* 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.util.GateBlockChangeSender;
import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin;
@ -28,13 +45,24 @@ public class CommandOpen extends BaseCommand
public void perform()
{
try
{
gate.setOpen(true);
try {
boolean needsGateManagerUpdate = false;
if (gate.getGateBlockLocations().isEmpty()) {
needsGateManagerUpdate = true;
}
gate.setOpen(true);
GateBlockChangeSender.updateGateBlocks(gate);
if (needsGateManagerUpdate) {
Plugin.getPlugin().getGatesManager().handleGateLocationChange(gate, null, null, null);
}
sendMessage(ChatColor.GREEN + "The gate was opened.");
}
catch (Exception e)
{
catch (Exception e) {
sendMessage(ChatColor.RED + e.getMessage());
}
}

View File

@ -0,0 +1,53 @@
/* 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.util.GateBlockChangeSender;
import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin;
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 = Plugin.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
senderMustBePlayer = false;
}
public void perform()
{
Plugin.getPlugin().getGatesManager().handleDeletion(gate);
GateBlockChangeSender.updateGateBlocks(gate, true);
sendMessage(ChatColor.GREEN + "Gate with id '" + gate.getId() + "' was deleted.");
}
}

View File

@ -1,8 +1,24 @@
/* 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 org.bukkit.ChatColor;
import de.craftinc.gates.Gate;
import de.craftinc.gates.GatesManager;
import de.craftinc.gates.Plugin;
@ -11,9 +27,8 @@ public class CommandRename extends BaseCommand
public CommandRename()
{
aliases.add("rename");
aliases.add("changename");
aliases.add("cn");
aliases.add("rn");
hasGateParam = true;
senderMustBePlayer = false;
@ -33,16 +48,19 @@ public class CommandRename extends BaseCommand
public void perform()
{
String newId = parameters.get(1);
GatesManager gatesManager = Plugin.getPlugin().getGatesManager();
try
{
Gate.rename(gate.getId(), newId);
sendMessage(ChatColor.GREEN + "Gate " + gate.getId() + " is now known as " + newId + ".");
}
catch (Exception e)
{
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,44 +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
{
gate.setExit(player.getLocation());
sendMessage(ChatColor.GREEN + "The exit of gate '" + gate.getId() + "' is now where you stand.");
}
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,58 @@
/* 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.util.GateBlockChangeSender;
import org.bukkit.ChatColor;
import de.craftinc.gates.Plugin;
public class CommandUnhide extends BaseCommand
{
public CommandUnhide()
{
aliases.add("unhide");
aliases.add("u");
requiredParameters.add("id");
helpDescription = "Make that gate visible";
requiredPermission = Plugin.permissionManage;
needsPermissionAtCurrentLocation = false;
shouldPersistToDisk = true;
senderMustBePlayer = false;
}
public void perform()
{
try
{
gate.setHidden(false);
GateBlockChangeSender.updateGateBlocks(gate);
sendMessage(ChatColor.GREEN + "The gate " + gate.getId() + " is now visible.");
}
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.listeners;
import de.craftinc.gates.Gate;
import de.craftinc.gates.Plugin;
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.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.isHidden()) {
try {
gate.setOpen(false);
}
catch (Exception ignored) { }
GateBlockChangeSender.updateGateBlocks(gate);
}
}
}

View File

@ -0,0 +1,34 @@
/* 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.PlayerChangedWorldEvent;
public class PlayerChangedWorldListener implements Listener
{
@EventHandler(priority = EventPriority.NORMAL)
public void onPlayerChangeWorld(PlayerChangedWorldEvent event)
{
GateBlockChangeSender.updateGateBlocks(event.getPlayer());
}
}

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.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)
{
GateBlockChangeSender.updateGateBlocks(event.getPlayer());
}
}

View File

@ -0,0 +1,169 @@
/* 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 java.util.Calendar;
import java.util.HashMap;
import de.craftinc.gates.util.ConfigurationUtil;
import de.craftinc.gates.util.GateBlockChangeSender;
import de.craftinc.gates.util.VehicleCloner;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
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.GatesManager;
import de.craftinc.gates.Plugin;
import org.bukkit.scheduler.BukkitScheduler;
public class PlayerMoveListener implements Listener
{
protected HashMap<String, Long> lastNoPermissionMessages = new HashMap<String, Long>();
@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());
}
final GatesManager gateManager = Plugin.getPlugin().getGatesManager();
final Gate gateAtLocation = gateManager.getGateAtLocation(event.getTo());
if ((gateAtLocation == null) || !gateAtLocation.isOpen()) {
return;
}
// Check for permission
if (!hasPermission(event.getPlayer(), gateAtLocation)
&& Plugin.getPlugin().getConfig().getBoolean(ConfigurationUtil.confShowTeleportNoPermissionMessageKey)) {
final String playerName = event.getPlayer().getName();
if (playerName == null) {
return;
}
// get the current time
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 = Plugin.getPlugin().getConfig().getString(ConfigurationUtil.confGateTeleportNoPermissionMessageKey);
event.getPlayer().sendMessage(ChatColor.RED + noPermissionString);
this.lastNoPermissionMessages.put(playerName, now);
}
}
else {
this.teleportPlayer(event.getPlayer(), gateAtLocation);
}
}
/**
* Teleports a player.
* @param player The player to teleport.
* @param gate The gate to which exit the player will be teleported.
*/
private void teleportPlayer(final Player player, final Gate gate)
{
// Destination
final Float newYaw = gate.getExit().getYaw() - gate.getLocation().getYaw() + player.getLocation().getYaw();
final Location destLocation = new Location( gate.getExit().getWorld(),
gate.getExit().getX(),
gate.getExit().getY(),
gate.getExit().getZ(),
newYaw,
player.getLocation().getPitch()
);
// Riding
final Entity vehicle = player.getVehicle();
final boolean vehicleIsSuitable = (vehicle != null) && (vehicle instanceof Vehicle);
if (vehicle != null && (!vehicleIsSuitable) || !gate.getAllowsVehicles()) {
if (!gate.getAllowsVehicles() && Plugin.getPlugin().getConfig().getBoolean(ConfigurationUtil.confShowTeleportNoPermissionMessageKey)) {
final String notAllowedMessage = Plugin.getPlugin().getConfig().getString(ConfigurationUtil.confGateTeleportVehicleNotAllowedMessageKey);
player.sendMessage(ChatColor.DARK_AQUA + notAllowedMessage);
}
return;
}
// (eject player)
if (vehicleIsSuitable) {
vehicle.eject();
vehicle.remove();
}
// Teleport
player.teleport(destLocation);
// Riding (mount player)
if (vehicleIsSuitable) {
final Plugin plugin = Plugin.getPlugin();
final BukkitScheduler scheduler = plugin.getServer().getScheduler();
destLocation.getChunk().load(); // load the destination chunk, no new entity will be created otherwise
scheduler.scheduleSyncDelayedTask(plugin, new Runnable() {
public void run()
{
// FIXME: the code below should be executed after the chunk got loaded and not after a fixed time!
// create a new entity at the destination location
final Vehicle newVehicle = VehicleCloner.clone((Vehicle)vehicle, destLocation);
newVehicle.setPassenger(player);
}
}, 2);
}
// Message
if (Plugin.getPlugin().getConfig().getBoolean(ConfigurationUtil.confShowTeleportMessageKey)) {
final String teleportMessage = Plugin.getPlugin().getConfig().getString(ConfigurationUtil.confGateTeleportMessageKey);
player.sendMessage(ChatColor.DARK_AQUA + teleportMessage);
}
}
protected boolean hasPermission(final Player player, final Gate gate)
{
if (Plugin.getPermission() == null) { // fallback: use the standard bukkit permission system
return player.hasPermission(Plugin.permissionUse);
}
else {
final boolean permAtLocation = Plugin.getPermission().has(gate.getLocation().getWorld(), player.getName(), Plugin.permissionUse);
final boolean permAtExit = Plugin.getPermission().has(gate.getExit().getWorld(), player.getName(), Plugin.permissionUse);
return permAtLocation && permAtExit;
}
}
}

View File

@ -0,0 +1,34 @@
/* 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,37 @@
/* 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 <20> 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,90 +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.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);
if (distToClosestGate < 2.0) {
this.currentGateAtEvent.put(player, closestGate);
return;
}
}
}
this.currentGateAtEvent.put(player, null);
}
}
}

View File

@ -0,0 +1,100 @@
/* 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 java.util.HashMap;
import java.util.Map;
import org.bukkit.Location;
import org.bukkit.World;
import de.craftinc.gates.Plugin;
public class LocationUtil
{
protected final static String worldKey = "world";
protected final static String xKey = "x";
protected final static String yKey = "y";
protected final static String zKey = "z";
protected static World getWorld(final String name) throws Exception
{
if (name == null) {
throw new IllegalArgumentException("The name of the world must not be 'null");
}
World world = Plugin.getPlugin().getServer().getWorld(name);
if (world == null) {
throw new Exception("World '" + name + "' does not exists anymore! Cannot get instance!");
}
return world;
}
/**
* Serializes a location. Helps storing locations inside yaml files. NOTE: We do not care about yaw
* and pitch for gate locations. So we won't serialize them.
*
* @param l The location to serialize. Supplying 'null' is ok..
* @return A Map object ready for storing inside a yaml file. Will return 'null' if 'l' is null.
*/
public static Map<String, Object> serializeLocation(final 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;
}
/**
*
* @param map A map generated with the 'serializeLocation' method. Supplying 'null' is ok.
* @return A deserialized location. This method will return 'null' if 'map' is null!
* @throws Exception This method will throw an exception if the world of the supplied serialized location
* does not exist or if 'map' does not contain all necessary keys!
*/
public static Location deserializeLocation(final Map<String, Object> map) throws Exception
{
if (map == null) {
return null;
}
World w = getWorld((String)map.get(worldKey));
Number x = (Number)map.get(xKey);
Number y = (Number)map.get(yKey);
Number z = (Number)map.get(zKey);
if (x == null || y == null || z == null) {
throw new IllegalArgumentException("Supplied map is invalid x, y or z coordinate was not supplied");
}
return new Location(w, x.doubleValue(), y.doubleValue(), z.doubleValue());
}
}

View File

@ -0,0 +1,74 @@
/* 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.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 == 0 && currentVersion >= 2) {
removePortalBlocks(gates);
updateAllowVehicles(gates);
return true;
}
else if (storageVersion == 1 && currentVersion >= 2) {
updateAllowVehicles(gates);
return true;
}
else {
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;
}
}
protected static void removePortalBlocks(List<Gate> gates)
{
for (Gate g : gates) {
for (Location l : g.getGateBlockLocations()) {
Block b = l.getBlock();
if (b.getType() == Material.PORTAL) {
b.setType(Material.AIR);
}
}
}
}
protected static void updateAllowVehicles(List<Gate> gates)
{
for (Gate g : gates) {
g.setAllowsVehicles(true);
}
}
}

View File

@ -0,0 +1,127 @@
/* 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 org.bukkit.Material;
import java.util.logging.Level;
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";
public static final String confGateMaterialKey = "gateMaterial";
public static GateMaterial getPortalMaterial()
{
String materialString = Plugin.getPlugin().getConfig().getString(confGateMaterialKey);
GateMaterial material = new GateMaterial();
if (materialString.equals("sapling")) {
material.material = Material.SAPLING;
}
else if (materialString.equals("water")) {
material.material = Material.STATIONARY_WATER;
}
else if (materialString.equals("lava")) {
material.material = Material.STATIONARY_LAVA;
}
else if (materialString.equals("cobweb")) {
material.material = Material.WEB;
}
else if (materialString.equals("grass")) {
material.material = Material.LONG_GRASS;
material.data = 1;
}
else if (materialString.equals("dead bush")) {
material.material = Material.DEAD_BUSH;
}
else if (materialString.equals("dandelion")) {
material.material = Material.YELLOW_FLOWER;
}
else if (materialString.equals("poppy")) {
material.material = Material.RED_ROSE;
}
else if (materialString.equals("brown mushroom")) {
material.material = Material.BROWN_MUSHROOM;
}
else if (materialString.equals("red mushroom")) {
material.material = Material.RED_MUSHROOM;
}
else if (materialString.equals("torch")) {
material.material = Material.TORCH;
}
else if (materialString.equals("redstone torch (off)")) {
material.material = Material.REDSTONE_TORCH_OFF;
}
else if (materialString.equals("redstone torch (on)")) {
material.material = Material.REDSTONE_TORCH_ON;
}
else if (materialString.equals("fence")) {
material.material = Material.FENCE;
}
else if (materialString.equals("nether portal")) {
material.material = Material.PORTAL;
}
else if (materialString.equals("iron bars")) {
material.material = Material.IRON_FENCE;
}
else if (materialString.equals("glass pane")) {
material.material = Material.THIN_GLASS;
}
else if (materialString.equals("fence gate")) {
material.material = Material.FENCE_GATE;
}
else if (materialString.equals("nether brick fence")) {
material.material = Material.NETHER_FENCE;
}
else if (materialString.equals("nether wart")) {
material.material = Material.NETHER_WARTS;
}
else if (materialString.equals("end portal")) {
material.material = Material.ENDER_PORTAL;
}
else if (materialString.equals("cobblestone wall")) {
material.material = Material.COBBLE_WALL;
}
else { // fallback!
material.material = Material.PORTAL;
Plugin.log(Level.WARNING, "Gate material invalid! Please check and correct your configuration file!");
}
return material;
}
}
class GateMaterial
{
public Material material = Material.PORTAL;
public byte data = 0;
}

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;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
@ -13,10 +30,8 @@ import de.craftinc.gates.Plugin;
public class FloodUtil
{
private final static int frameBlockSearchLimit = 40;
private static final Set<BlockFace> exp1 = new HashSet<BlockFace>();
private static final Set<BlockFace> exp2 = new HashSet<BlockFace>();
protected static final Set<BlockFace> exp1 = new HashSet<BlockFace>();
protected static final Set<BlockFace> exp2 = new HashSet<BlockFace>();
static
{
@ -30,62 +45,158 @@ public class FloodUtil
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'.
*/
public static Set<Block> getFrame(final Set<Block> blocks)
{
if (blocks == null || blocks.isEmpty()) {
return new HashSet<Block>();
}
// try to find gate's direction (north-south or east-west)
Set<BlockFace> gateFrameSearchFaces = null;
for (Block b : blocks) {
if (blocks.contains(b.getRelative(BlockFace.EAST)) ||
blocks.contains(b.getRelative(BlockFace.WEST))) {
gateFrameSearchFaces = exp1;
break;
}
if (blocks.contains(b.getRelative(BlockFace.NORTH)) ||
blocks.contains(b.getRelative(BlockFace.SOUTH))) {
gateFrameSearchFaces = exp2;
break;
}
}
if (gateFrameSearchFaces != null) {
return _getFrame(blocks, gateFrameSearchFaces);
}
else { // no direction found (the gate might only consist of blocks one over another)
// Try one direction and check if the found blocks are not air.
// If air is found (frame broken or wrong direction) return the other direction
Set<Block> frameBlocks = _getFrame(blocks, exp1);
for (Block b : frameBlocks) {
if (b.getType() == Material.AIR) {
return _getFrame(blocks, exp2);
}
}
return frameBlocks;
}
}
protected static Set<Block> _getFrame(final Set<Block> blocks, final Set<BlockFace> searchDirections)
{
Set<Block> frameBlocks = new HashSet<Block>();
for (Block b : blocks) {
for (BlockFace bf : searchDirections) {
Block bb = b.getRelative(bf);
if (!blocks.contains(bb)) {
frameBlocks.add(bb);
}
}
}
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<Block>();
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> getGateFrameBlocks(Block block)
public static Set<Block> getGatePortalBlocks(final Block block)
{
Set<Block> blocks1 = getAirFloodBlocks(block, new HashSet<Block>(), exp1, frameBlockSearchLimit);
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)
{
if (blocks1 == null && blocks2 == null) {
return null;
}
if (blocks1 == null)
{
if (blocks1 == null) {
return blocks2;
}
if (blocks2 == null)
{
if (blocks2 == null) {
return blocks1;
}
if (blocks1.size() > blocks2.size())
{
if (blocks1.size() > blocks2.size()) {
return blocks2;
}
return blocks1;
}
private static Set<Block> getAirFloodBlocks(Block startBlock, Set<Block> foundBlocks, Set<BlockFace> expandFaces, int limit)
protected static Set<Block> getAirFloodBlocks(final Block startBlock,
Set<Block> foundBlocks,
final Set<BlockFace> expandFaces,
int limit)
{
if (foundBlocks == null)
{
if (foundBlocks == null) {
return null;
}
if (foundBlocks.size() > limit)
{
if (foundBlocks.size() > limit) {
Plugin.log(Level.ALL, "exceeding gate size limit.");
return null;
}
if (foundBlocks.contains(startBlock))
if (foundBlocks.contains(startBlock)) {
return foundBlocks;
}
if (startBlock.getType() == Material.AIR || startBlock.getType() == Material.PORTAL)
{
if (startBlock.getType() == Material.AIR) {
// ... We found a block :D ...
foundBlocks.add(startBlock);
// ... And flood away !
for (BlockFace face : expandFaces)
{
for (BlockFace face : expandFaces) {
Block potentialBlock = startBlock.getRelative(face);
foundBlocks = getAirFloodBlocks(potentialBlock, foundBlocks, expandFaces, limit);
}
@ -93,5 +204,4 @@ public class FloodUtil
return foundBlocks;
}
}

View File

@ -0,0 +1,252 @@
/* 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.Gate;
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!
*/
public static void temporaryHighlightGatesFrames(final Player player, final Set<Gate> gates)
{
if (player == null) {
throw new IllegalArgumentException("'player' must not be 'null'!");
}
if (gates == null) {
throw new IllegalArgumentException("'gate' must not be 'null!");
}
for (Gate g : gates) {
Set<Block> frameBlocks = g.getGateFrameBlocks();
for (Block b : frameBlocks) {
player.sendBlockChange(b.getLocation(), Material.GLOWSTONE, (byte)0);
}
}
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);
}
public static void temporaryHighlightGateFrame(final Player player, final Gate gate)
{
if (gate == null) {
throw new IllegalArgumentException("'gate' must not be 'null!");
}
if (player == null) {
throw new IllegalArgumentException("'player' must not be 'null'!");
}
Set<Block> frameBlocks = gate.getGateFrameBlocks();
for (Block b : frameBlocks) {
player.sendBlockChange(b.getLocation(), Material.GLOWSTONE, (byte)0);
}
Plugin plugin = Plugin.getPlugin();
long highlightDuration = 20 * plugin.getConfig().getLong(confHighlightDurationKey);
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
dehighlightGateFrame(player, gate);
}
}, highlightDuration);
}
protected 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);
}
}
}
protected static void dehighlightGateFrame(final Player player, final Gate gate)
{
Set<Block> frameBlocks = gate.getGateFrameBlocks();
for (Block b : frameBlocks) {
player.sendBlockChange(b.getLocation(), b.getType(), (byte)0);
}
}
/**
* 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)
{
if (player == null) {
throw new IllegalArgumentException("'player' must not be 'null'!");
}
if (location == null) {
throw new IllegalArgumentException("'location' must not be 'null'!");
}
Set<Gate> gatesNearby = Plugin.getPlugin().getGatesManager().getNearbyGates(location.getChunk());
GateMaterial gateMaterial = getPortalMaterial();
if (gatesNearby == null) {
return; // no gates nearby
}
for (Gate g : gatesNearby) {
if (!g.isOpen() || g.isHidden()) {
continue;
}
for (Location l : g.getGateBlockLocations()) {
if (l.getBlock().getType() == Material.AIR) {
player.sendBlockChange(l, gateMaterial.material, gateMaterial.data);
}
}
}
if (sendDelayed) {
Bukkit.getScheduler().scheduleSyncDelayedTask(Plugin.getPlugin(), new Runnable()
{
@Override
public void run()
{
updateGateBlocks(player, location, false);
}
}, 20L);
}
}
/**
* This method calls: updateGateBlocks(player, location, false);
*/
public static void updateGateBlocks(final Player player, final Location location)
{
updateGateBlocks(player, location, false);
}
/**
* This method calls: updateGateBlocks(player, player.getLocation(), false);
*/
public static void updateGateBlocks(final Player player)
{
if (player == null) {
throw new IllegalArgumentException("'player' must not be 'null'!");
}
updateGateBlocks(player, player.getLocation(), 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)
{
if (gate == null) {
throw new IllegalArgumentException("'gate must not be 'null'!");
}
Location gateLocation = gate.getLocation();
if (gate.getGateBlockLocations().isEmpty()) {
return;
}
ArrayList<Player> playersNearby = new ArrayList<Player>();
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);
}
}
GateMaterial gateMaterial = getPortalMaterial();
Material material;
byte data = 0;
if (gate.isOpen() && !gate.isHidden() && !remove) {
material = gateMaterial.material;
data = gateMaterial.data;
}
else {
material = Material.AIR;
}
for (Player p : playersNearby) {
for (Location l : gate.getGateBlockLocations()) {
if (l.getBlock().getType() == Material.AIR) { // on server-side a gate is always made out of 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

@ -0,0 +1,79 @@
/* 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 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,95 @@
/* 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 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

@ -1,21 +1,43 @@
/* 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 org.bukkit.ChatColor;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.Material;
public class TextUtil
{
public static String titleize(String str)
public static String titleize(String str)
{
String line = ChatColor.GOLD + repeat("_", 60);
String center = ".[ " + ChatColor.YELLOW + str + ChatColor.GOLD + " ].";
int pivot = line.length() / 2;
int eatLeft = center.length() / 2;
int eatRight = center.length() - eatLeft;
return line.substring(0, pivot - eatLeft) + center + line.substring(pivot + eatRight);
if (center.length() >= 60) {
return ChatColor.GOLD + center;
}
else {
String line = ChatColor.GOLD + repeat("_", 60);
int pivot = line.length() / 2;
int eatLeft = center.length() / 2;
int eatRight = center.length() - eatLeft;
return line.substring(0, pivot - eatLeft) + center + line.substring(pivot + eatRight);
}
}
@ -29,7 +51,7 @@ public class TextUtil
/**
* 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)
{
@ -45,24 +67,6 @@ public class TextUtil
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);
}
}

View File

@ -0,0 +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.util;
import org.bukkit.Location;
import org.bukkit.entity.*;
public class VehicleCloner
{
public static Vehicle clone(Vehicle parent, Location cloneLocation)
{
Vehicle clone = cloneLocation.getWorld().spawn(cloneLocation, parent.getClass());
clone.setFallDistance(parent.getFallDistance());
clone.setFireTicks(parent.getFireTicks());
clone.setVelocity(parent.getVelocity());
clone.setTicksLived(parent.getTicksLived());
clone.setLastDamageCause(parent.getLastDamageCause());
if (clone instanceof Boat) {
Boat boat = (Boat)clone;
Boat parentBoat = (Boat)parent;
boat.setMaxSpeed(parentBoat.getMaxSpeed());
boat.setOccupiedDeceleration(parentBoat.getOccupiedDeceleration());
boat.setUnoccupiedDeceleration(parentBoat.getUnoccupiedDeceleration());
boat.setWorkOnLand(parentBoat.getWorkOnLand());
boat.setVelocity(parentBoat.getVelocity());
}
else if (clone instanceof Animals) {
Animals animal = (Animals)clone;
Animals parentAnimal = (Animals)parent;
animal.setMaxHealth(parentAnimal.getMaxHealth());
animal.setHealth(parentAnimal.getMaxHealth());
animal.setRemainingAir(parentAnimal.getRemainingAir());
animal.setMaximumAir(parentAnimal.getMaximumAir());
animal.setMaximumNoDamageTicks(parentAnimal.getMaximumNoDamageTicks());
animal.setLastDamage(parentAnimal.getLastDamage());
animal.setNoDamageTicks(parentAnimal.getNoDamageTicks());
animal.addPotionEffects(parentAnimal.getActivePotionEffects());
animal.setRemoveWhenFarAway(parentAnimal.getRemoveWhenFarAway());
animal.setCanPickupItems(parentAnimal.getCanPickupItems());
animal.setCustomName(parentAnimal.getCustomName());
animal.setCustomNameVisible(parentAnimal.isCustomNameVisible());
animal.setTarget(parentAnimal.getTarget());
animal.setAge(parentAnimal.getAge());
animal.setAgeLock(parentAnimal.getAgeLock());
if (clone instanceof Horse) {
Horse horse = (Horse)clone;
Horse parentHorse = (Horse)parent;
horse.getInventory().setArmor(parentHorse.getInventory().getArmor());
horse.getInventory().setSaddle(parentHorse.getInventory().getSaddle());
horse.setCarryingChest(parentHorse.isCarryingChest());
horse.getInventory().setContents(parentHorse.getInventory().getContents());
horse.setTamed(parentHorse.isTamed());
horse.setOwner(parentHorse.getOwner());
horse.setJumpStrength(parentHorse.getJumpStrength());
horse.setMaxDomestication(parentHorse.getMaxDomestication());
horse.setDomestication(parentHorse.getDomestication());
horse.setStyle(parentHorse.getStyle());
horse.setColor(parentHorse.getColor());
horse.setVariant(parentHorse.getVariant());
if (parentHorse.isAdult()) {
horse.setAdult();
}
else {
horse.setBaby();
}
horse.setBreed(parentHorse.canBreed());
}
else if (clone instanceof Pig) {
Pig pig = (Pig)clone;
Pig parentPig = (Pig)parent;
pig.setSaddle(parentPig.hasSaddle());
}
}
else if (clone instanceof Minecart) {
Minecart minecart = (Minecart)clone;
Minecart parentMinecart = (Minecart)parent;
minecart.setDerailedVelocityMod(parentMinecart.getDerailedVelocityMod());
minecart.setFlyingVelocityMod(parentMinecart.getFlyingVelocityMod());
minecart.setSlowWhenEmpty(parentMinecart.isSlowWhenEmpty());
minecart.setMaxSpeed(parentMinecart.getMaxSpeed());
minecart.setDamage(parentMinecart.getDamage());
minecart.setVelocity(parentMinecart.getVelocity());
}
return clone;
}
}