Compare commits

389 Commits

Author SHA1 Message Date
bendude56
f210234e59 Update JavaDocs regarding teleportation of entities. Fixes BUKKIT-4210
Up until Minecraft version 1.5 it was not possible to teleport entities
within vehicles. With the 1.5 update came the change in the Minecraft
teleportation logic to dismount before teleporting the entity, if
applicable.

This commit simply ammends the JavaDocs for the associated CraftBukkit
half regarding the action the teleportation methods will take before
completing a teleport.
2014-08-17 11:49:33 -06:00
Jerom van der Sar
e0dc9470ef Add ability to keep items on death via plugins. Adds BUKKIT-5724
When a player dies their inventory is normally scattered over the the area
in which they died. Plugins should be able to modify this behaviour by
defining whether or not the player's inventory will be dropped on the ground or
waiting for the player when they eventually respawn.

This commit adds the methods required to the PlayerDeathEvent for plugins
to be able to incorporate the behaviour mentioned as a simple boolean
flag.
2014-08-17 11:40:42 -06:00
riking
f3a23c4985 Rename Fish to FishHook. Fixes BUKKIT-3856
"Fish" is a badly named class to represent a fishing hook due to the
possibility (or lack of) that Minecraft may be getting fish entities.

This commit provides potential future compatibility by deprecating the
existing Fish class and moving the methods to a new class: FishHook.
2014-08-17 11:36:06 -06:00
bendem
93732941ac Only loop through op players when tab completing /deop Fixes BUKKIT-5748
When tab completing /deop, a potentially large set of players is used for
finding suitable player names. This potentially large set of players can
cause performance concerns on servers. To fix this, only the set of
operators should be considered for the /deop tab completion where the
player set is much more relevant and follows suit with other commands
which employ "more specific" player sets when possible. This commit adds
this more efficient behaviour.
2014-08-16 19:55:15 -06:00
Wesley Wolfe
8d5b4c1e9a Add deprecated BukkitRunnable overloads in the scheduler. Adds BUKKIT-5752 2014-08-07 19:26:52 -05:00
Travis Watkins
d3ab9468c3 Recalculate damage modifiers in event for old method. Fixes BUKKIT-5681
When we added the new API in EntityDamageEvent to give control over the
various things that modify the final damage done we caused a change in
behavior for users of the old #setDamage(double) method. Before changing
the damage would happen before the modifiers were calculated so they would
be based on the final damage value from the event. Now they are calculated
at the beginning so changing the damage does not change the modifiers.

To allow the old style and the new to coexist we now expose the vanilla
modifer calculations to the event in the form of Function objects. These
are used in #setDamage(double) to calculate the difference in the modifier
between the old damage and the new and apply this difference to the current
modifier. The difference is between the vanilla values for both damage
values and is applied on top of the event's modifier value as this should
make old and new API usage work together in a way that isn't surprising.
2014-07-09 19:00:16 -05:00
Wesley Wolfe
7e73c85e78 Pulling all pending Bukkit-JavaDoc changes 2014-07-08 23:56:15 -05:00
Travis Watkins
cc3e3b841f Update Bukkit for Minecraft 1.7.10 2014-06-25 20:29:14 -05:00
Wesley Wolfe
0d9771acf6 Replace getOnlinePlayers to provide a view. Adds BUKKIT-5668 2014-06-25 15:56:56 -05:00
Wesley Wolfe
c025253012 Add damage modifier API in EntityDamageEvent. Adds BUKKIT-347, BUKKIT-4104
This commit adds API for the enchantment, armor, potion and other
modifications to damage done to an entity. These damage modifiers are each
editable editable via a getter and a setter. This addition allows for more
accurate modification and monitoring of damage done to/by an entity, as it
displays the final damage done as well.
2014-06-22 15:28:02 -05:00
Wesley Wolfe
028525f8fc Fix failing BukkitMirrorTest 2014-06-03 16:09:47 -05:00
Wesley Wolfe
91bd9e9314 Rewrite BukkitMirrorTest 2014-06-03 16:09:47 -05:00
EvilSeph
fc7109d4d1 Updated version to 1.7.9-R0.3-SNAPSHOT for development towards next release. 2014-06-01 02:36:00 -04:00
EvilSeph
9b2d3d1a5a Updated version to 1.7.9-R0.2 in pom.xml for Beta. 2014-06-01 01:44:03 -04:00
EvilSeph
9141084881 Updated version to 1.7.9-R0.2-SNAPSHOT for development towards next release. 2014-05-14 23:36:41 -04:00
EvilSeph
21c8713ca2 Updated version to 1.7.9-R0.1 in pom.xml for Beta. 2014-05-14 22:40:49 -04:00
Wesley Wolfe
24883a6170 Change YamlConfiguration encoding styles.
On JVMs with UTF-8 default encoding, this commit has no change in behavior.

On JVMs with ascii default encoding (like some minimal linux installa-
tions), this commit now uses UTF-8 for YamlConfiguration operations.
Because all ascii is valid UTF-8, there is no feature degradation or data
loss during the transition.

On JVMs with any non-unicode but ascii-compliant encoding, this commit now
forces YamlConfiguration to escape special characters when writing to
files, effectively rendering the encoding to be plain ascii. Any affected
file will now be able to migrate to UTF-8 in the future without data-loss
or explicit conversion. When reading files, YamlConfiguration will use the
system default encoding to handle any incoming non-utf8 data, with the
expectation that any newly written file is still compliant with the
system's default encoding.

On JVMs with any non-unicode, but ascii-incompliant encoding (this may be
the case for some Eastern character sets on Windows systems), this change
is breaking, but is justified in claim that these systems would otherwise
be unable to read YamlConfiguration for implementation dependent settings
or from plugins themselves. For these systems, all uses of the encoding
will be forced to use UTF-8 in all cases, and is effectively treated as if
it was configured to be UTF-8 by default.

On JVMs with unicode encoding of UTF-16 or UTF-32, the ability to load any
configurations from almost any source prior to this change would have been
unfeasible, if not impossible. As of this change, however, these systems
now behave as expected when writing or reading files. However, when
reading from any plugin jar, UTF-8 will be used, matching a super-majority
of plugin developer base and requirements for the plugin.yml.

Plugin developers may now mark their plugin as UTF-8 compliant, as
documented in the PluginDescriptionFile class. This change will cause the
appropriate APIs in JavaPlugin to ignore any system default encoding,
instead using a Reader with the UTF-8 encoding, effectively rendering the
jar system independent. This does not affect the aformentioned JVM
settings for reading and writing files.

To coincide with these changes, YamlConfiguration methods that utilize a
stream are now deprecated to encourage use of a more strict denotation.
File methods carry system-specific behaviors to prevent unncessary data
loss during the transitional phase, while Reader methods are now provided
that have a very well-defined encoder behavior. For the transition from
InputStream methods to Reader methods, an API has been added to JavaPlugin
to provide a Reader that matches the previous behavior as well as
compliance to the UTF-8 flag in the PluginDescriptionFile.

Addresses BUKKIT-314, BUKKIT-1466, BUKKIT-3377
2014-05-14 07:07:37 -05:00
Wesley Wolfe
8291081082 Add awake flag for bats. Adds BUKKIT-5606 2014-05-13 20:39:02 -05:00
eueln
aa8336ec6a Allow inventory creation by InventoryType and title. Fixes BUKKIT-4045
Up until now it has not been possible to create a new Inventory using
a custom title and permit any InventoryType available.

The commit changes that by adding a method to optionally supply the title
for the given inventory type and holder, creating the functionality to
display any supported inventory type with a 32 character length String.

If the inventory title supplied is larger than 32 characters then an
IllegalArgumentException is thrown stating so.
2014-05-01 17:18:20 -06:00
eueln
236ebabda2 Account for spacing in MapFont#getWidth(). Fixes BUKKIT-4089
Prior to this commit MapFont#getWidth() did not account for the 1px
spacing inserted by CraftMapCanvas#drawText().

This commit adds the consideration of the 1px spacing per character
while taking care to not consider the last character as it will not
have a 1px space behind it. This commit also ensures the method will
not check a 0-length String.
2014-05-01 17:10:11 -06:00
LordRalex
e802978b3c Add missing entity effects. Adds BUKKIT-3311
There are many effects that were not present in the API prior to
this commit. These effects are being used by the implementation,
but cannot be accessed via plugins.

This commit exposes these effects using the EntityEffects enum,
allowing for plugin authors to make use of these effects. However,
many of the effects require certain conditions to be met before
they will be visible to the client, much like some of the existing
effects.
2014-04-30 22:56:09 -06:00
GJ
b9a0f9759d [Bleeding] Add COCOA_TREE to list of possible tree types. 2014-04-28 10:17:12 -04:00
Nate Mortensen
41d9f93da7 Add BlockMultiPlaceEvent. Adds BUKKIT-5558
Some blocks, such as beds, doors, or flowers, are actually composed of
multiple blocks when they are placed.  Currently, to detect how many
blocks are actually modified a plugin has to perform various calculations
to determine the directions of relative blocks, many of which are
difficult to perform and can easily return false positives.

This commit adds in a BlockMultiPlaceEvent, which adds in easy support for
accessing all blocks modified by the placement of a block.
2014-04-21 20:28:59 -06:00
GJ
f7163d78a6 [Bleeding] Add new TargetReasons to EntityTargetEvent.
This commit adds three new TargetReasons to EntityTargetEvent to address
missing cases where the event is not currently fired.

The first, TargetReason.TARGET_ATTACKED_NEARBY_ENTITY, is used when a
neutral wolf is attacked, causing all nearby wolves to turn hostile and
attack the first wolf's target.

The second, TargetReason.REINFORCEMENT_TARGET, is used when a zombie summons
reinforcements and the new zombie targets the first zombie's target.

The third, TargetReason.COLLISION, is used when an iron golem collides with
a hostile entity, causing it to begin targeting the entity it collided with.
2014-04-18 10:35:34 -05:00
GJ
ded772d572 [Bleeding] Add SpawnReasons to cover new Minecraft features.
Adds BUKKIT-5370, BUKKIT-5378, BUKKIT-5382, BUKKIT-5482. Covers zombie
villagers, ocelot babies, silverfish popping out of blocks, and mobs
spawning with a mount.
2014-04-18 09:19:20 -05:00
GJ
8f42f10cb9 [Bleeding] Use proper teleport reason for /tp command. Fixes BUKKIT-5348
Previously, when calling the /tp command with coordinates, no TeleportCause
was passed, causing the resulting PlayerTeleportEvent to be called with
TeleportCause.PLUGIN instead of TeleportCause.COMMAND. This commit adds the
missing TeleportCause to ensure that the resulting PlayerTeleportEvent
reports the correct TeleportCause.
2014-04-18 08:41:48 -05:00
Travis Watkins
8652e1ff28 Update Bukkit for Minecraft 1.7.9 2014-04-17 13:44:58 -05:00
Travis Watkins
76d7dff75e Revert changes to ban API from 1.7.8 2014-04-17 10:44:02 -05:00
Travis Watkins
f13accabe1 Revert additions to skull BlockState API from 1.7.8 2014-04-17 08:40:04 -05:00
Travis Watkins
ec19988db3 Add methods to use arbitrary entries in scoreboards. Adds BUKKIT-3977 2014-04-13 23:09:40 -05:00
Travis Watkins
8c0271cf92 Update Bukkit for Minecraft 1.7.8 2014-04-11 22:29:37 -05:00
Patrick Seidel
5011115726 Add method to send fake sign updates to players. Adds BUKKIT-2300 2014-04-02 18:04:05 -05:00
BlackHole
e5f17c41f4 Add player unique ID to (Async)PlayerPreLoginEvent. Adds BUKKIT-5108 2014-04-02 17:31:48 -05:00
Wesley Wolfe
1741b91175 Deprecate missed magic values from 1f83111208 2014-04-01 20:51:17 -05:00
Travis Watkins
4bc86be459 Add API for dealing with player UUIDs. Adds BUKKIT-5071, BUKKIT-5501 2014-03-29 16:49:09 -05:00
Wesley Wolfe
55c8f0a007 Pulling all pending Bukkit-JavaDoc changes 2014-03-24 13:20:52 -05:00
t00thpick1
4a47cf3e83 [Bleeding] Add direct addresses for command aliases. 2014-03-22 16:45:34 -04:00
t00thpick1
fa88ff4138 [Bleeding] Plugin aliases should have higher priority than fallbacks. Fixes BUKKIT-5442 2014-03-22 16:42:39 -04:00
mbax
c687bbc113 Update Bukkit to 1.7.5 2014-03-22 16:24:08 -04:00
Wesley Wolfe
18064cc277 Update data folder migration for spaces in plugin names. Fixes BUKKIT-5417
This change drops the previous plugin data folder migration based on the
plugin's file name, and adapts the migration to now instead consider
plugins that have spaces in their original name.
2014-02-15 12:16:07 -06:00
Wesley Wolfe
37da49c4c3 Provide warnings for spaces in plugin names. Addresses BUKKIT-5419 2014-02-15 12:16:03 -06:00
Wesley Wolfe
543b253dd8 Fix loadbefore, soft, and normal dependencies with spaces. Fixes BUKKIT-5418
This change makes the lists of loadbefore, softdependency, and dependency
replace the spaces in the names with underscored to reflect the behavior
used with names.
2014-02-15 12:12:13 -06:00
EvilSeph
66daa8a96c Updated version to 1.7.2-R0.4-SNAPSHOT for development towards next release. 2014-02-12 01:58:55 -05:00
EvilSeph
f2b4a4c32b Updated version to 1.7.2-R0.3 in pom.xml for Beta. 2014-02-12 01:33:04 -05:00
t00thpick1
d45788bbf9 [Bleeding] Update Tell and Help aliases to use alias system. 2014-02-10 17:19:39 -06:00
Travis Watkins
c9581cec84 Remove extra events from alias execution.
When executing an alias we already call an event for the alias itself. The
extra events are not needed for logging purposes as the alias itself is
logged and the events cause issues for plugins trying to do spam checking
on their own.
2014-02-10 16:18:36 -06:00
Travis Watkins
fa7b3c26c8 Clean up alias handling.
There is no need to print a stacktrace when an alias fails, we do not do
this for normal commands. We also now give error messages when attempting
to register an alias instead of having them just silently not function.
2014-02-09 23:16:19 -06:00
t00thpick1
18a2a9f5bf [Bleeding] Support any number of arguments in aliases 2014-02-09 20:12:04 -05:00
t00thpick1
3dfe3d1594 [Bleeding] Implement escape sequence for aliases. 2014-02-09 19:25:46 -05:00
t00thpick1
72a6f60a53 [Bleeding] Fix getCommand for conflicting plugin commands. 2014-02-09 19:25:46 -05:00
t00thpick1
64481e3e24 [Bleeding] Also blacklist ":" in plugin command aliases. 2014-02-08 15:50:59 -05:00
t00thpick1
ca3433b1bd [Bleeding] Fix formatting of optional arguments. 2014-02-08 15:50:58 -05:00
Wesley Wolfe
9fc4d38e14 Pulling all pending Bukkit-JavaDoc changes 2014-02-08 06:05:41 -05:00
t00thpick1
5023fe375e [Bleeding] Improve alias system.
Adds a large expansion of the aliases system. Aliases can now take arguments,
reorder their arguments, and only pass certain arguments to certain commands.
New syntax added to the aliases are $1 for optional arguments, $$1 for
required arguments, $1- for optionally using all the arguments from the
specified position onward, and $$1- to do the same thing but require at least
the specified position exist. These exist for numbers 1 through 9. You are
able to pass arguments to one command of a multiple command argument and not
others. You can also use the argument as a prefix and/or suffix. A raw $ can
be represented in the arguments by using \$.

Examples:

aliases:
# Usage: /testobjective score_deaths 1 5
testobjective:
- "testfor @p[$$1=$$3,$$1_min=$$2]"

# Usage: /ban Amaranthus Because reasons
ban:
- ban $$1 $2-
- say Banned $$1

# Usage: /icanhasbukkit
icanhasbukkit:
- version

# Usage: /icanhasplugin HomeBukkit
icanhasplugin:
- version $$1

One change from the previous aliases system is that commands are no longer
passed all arguments implicitly. You must explicitly pass the arguments
you want to pass to the command.
2014-02-08 03:11:46 -06:00
t00thpick1
d7e0197e9d [Bleeding] Simplify command handling.
Instead of duplicating code to handle two pools of commands
we can instead just add the fallback commands after all
plugin commands are loaded and achieve the same effect. We
also now always register the direct address of a command
to ensure it is always possible to access it.

In addition, aliases can be determined by whether or not
the command label of the command matches the command address,
thereby rendering the aliases HashSet redundant.
2014-02-08 03:11:46 -06:00
t00thpick1
a2b5d6a907 [Bleeding] Blacklist ":" in command names. 2014-02-08 03:11:46 -06:00
t00thpick1
1d11e1d940 [Bleeding] Blacklist certain plugin names 2014-02-08 03:11:46 -06:00
mbax
75427e084d Add banning API and resolve associated command issues. Adds BUKKIT-3535.
Fixes BUKKIT-5371 and BUKKIT-4285

Prior to this commit, ban reasons were not supported by banning commands.
Additionally, the player(s) affected by the ban-ip command would not have
been removed from the server via a kick.

The Bukkit API lacked support for modifying various attributes associated
with bans, such as the reason and expiration date. This caused various plugins
to use external or other means to store a ban reason, making the built-in
banning system on the server partially useless.

Now the ban commands will accept reasons for the bans as well as kick the
player from the server once banned. That means that if an IP is banned
that all players using that IP will be removed from the server.

The API provided now supports editing the ban reason, creation date,
expiration date and source. The ban list has also been created to
provide this information more easily. Editing the data requires an
implementing plugin to manually save the information with the provided
method in BanEntry or BanList once changes have been made.

The addition of this API has deprecated the use of OfflinePlayer#setBanned()
as it has been replaced by BanList#addBan().
2014-02-07 23:49:44 -07:00
Kodekpl
574f7a8c6c Added SpawnReasons for nether portals and dispensers. Fixes BUKKIT-3148
Previously any entities spawned through dispensers (monster eggs) or
by nether portals were given the incorrect SpawnReason of SPAWNER_EGG.
This made it impossible to distinguish what exactly happened in regards
to the creature being spawned.

With the additional two SpawnReasons, plugins can identify sources of
creature spawning more easily and accuratly.
2014-02-01 22:08:48 -07:00
t00thpick1
a621d1683a [Bleeding] Add setCharged and getCharged to WitherSkull. Adds BUKKIT-3060 2014-01-30 21:58:48 -07:00
t00thpick1
d8a295202c [Bleeding] Add ProjectileSource interface. Addresses BUKKIT-1038, BUKKIT-1156 2014-01-30 21:58:48 -07:00
MorphanOne
018048333e Add setCritical and isCritical methods to Arrow.java. Adds BUKKIT-5113 2014-01-30 21:58:48 -07:00
Likaos
9510913a19 Add methods to get and set knockback strength in Arrow. Adds BUKKIT-5103 2014-01-30 21:58:47 -07:00
GJ
43d61f134c [Bleeding] Fix logic for calculating slot in Creative mode. Fixes BUKKIT-4715
Previously, hotbar slots for player inventory would return 9 - 18 while in
Creative mode, rather than 0 - 9. This commit fixes the logic used for
calculating the returned slot based on the raw slot.
2014-01-25 18:14:52 -06:00
Wesley Wolfe
4b0e6ba611 Add ServerListPingEvent player list API. Adds BUKKIT-5121, BUKKIT-2465 2014-01-19 15:56:09 -06:00
t00thpick1
fe360273a5 [Bleeding] Add /achievement command. Addresses BUKKIT-4932 2014-01-16 00:50:49 -06:00
t00thpick1
d4802061ec [Bleeding] Fix Achievement and Statistic API. Fixes BUKKIT-5305 2014-01-16 00:50:43 -06:00
Wesley Wolfe
ce94a3555c Modify give command to support 1.7 features. Fixes BUKKIT-5286
Necessary additions include an interface to add internal value conversions
that are inappropriate for proper API design. This acts as a substitute
for properly formed, user-friendly commands in an effort to maintain
relatively vanilla behavior.
2014-01-14 22:37:00 -06:00
t00thpick1
bff28d83d9 [Bleeding] Add 1.7 setworldspawn and setidletimeout commands. Addresses BUKKIT-4932 2014-01-14 19:05:14 -05:00
Wesley Wolfe
ccc56c8f7e Fix some messages
Addresses BUKKIT-5272, BUKKIT-5282, and BUKKIT-5283
2014-01-06 14:20:22 -06:00
Wesley Wolfe
10d8fe58d3 Use region matching instead of sub-strings. Addresses BUKKIT-5275 2014-01-04 12:50:19 -06:00
Wesley Wolfe
45ed9a3ab1 Add unit tests for org.bukkit.util.StringUtil 2014-01-04 12:43:49 -06:00
Wesley Wolfe
3fcbcaf427 Add method to get plugin by its class. Adds BUKKIT-5240
Currently, the only way to get a plugin is by name or using a static
variable. This adds two methods to get a plugin based on its classes,
utilizing the plugin classloader.
2013-12-24 22:20:20 -06:00
Wesley Wolfe
bc77402b9b [BREAKING] Shift plugin initialization; Addresses BUKKIT-1788
This reverts commit ae4f1c05d8, restoring
commit 27cb5e7c9c (mostly).

Shared class loading was removed as an explicit feature in the plugin.yml,
as all plugins implicitly share class loaders already.

Some deprecated, internal functionality is now (package) private, namely
some sections pointed out in 203de4180b.
2013-12-24 22:18:52 -06:00
EvilSeph
1227b64c8a Updated version to 1.7.2-R0.3-SNAPSHOT for development towards next release. 2013-12-21 03:08:33 -05:00
EvilSeph
53c6314428 Updated version to 1.7.2-R0.2 in pom.xml for Beta. 2013-12-21 02:51:08 -05:00
EvilSeph
00aac779b2 Handle commandBlockOutput GameRule for Command Minecarts.
Fixes BUKKIT-5207
2013-12-20 23:35:10 -05:00
EvilSeph
80a81d2605 Updated version to 1.7.2-R0.2-SNAPSHOT for development towards next release. 2013-12-18 01:01:04 -05:00
EvilSeph
e68a717a91 Updated version to 1.7.2-R0.1 in pom.xml for Beta. 2013-12-18 00:23:20 -05:00
Nate Mortensen
1da4a6458f Add new setResourcePack method. Fixes BUKKIT-5015
Minecraft now uses resource packs instead of texture packs.

This commit adds a new method specific for resource packs, and deprecates
setTexturePack.
2013-12-17 20:15:16 -07:00
Peter Olson
6f66d7407a Specify MaterialData for Acacia and Dark Oak stairs. Fixes BUKKIT-5037
When Minecraft 1.7 was released, Acacia and Dark Oak Stairs were added.
While Bukkit added them to Material.java, it did not add the MaterialData
mapping of them to Stairs.class.

Currently getAscendingDirection() and other stair-specific functions can
not be used on these new stairs. This commit fixes that by adding the
mapping needed.

Pulled from PR #977
2013-12-16 19:48:17 -07:00
BlackHole
b9cc5c85d2 Add missed tree types for Minecraft 1.7. Adds BUKKIT-5042
The Minecraft 1.7 update added two new types of trees that weren't added
in the initial update to 1.7: MEGA_REDWOOD and TALL_BIRCH.

Pulled from PR #979
2013-12-16 19:48:16 -07:00
GJ
fec13fc826 [Bleeding] Correct naming of sounds for Minecraft 1.7. Fixes BUKKIT-5065
Several sounds were renamed in Minecraft 1.7 and have been updated
accordingly. Additionally, two sounds, HURT and BREATH, were removed from
Minecraft.
2013-12-16 19:48:16 -07:00
Wesley Wolfe
8a1dbc38da Pulling all pending Bukkit-JavaDoc changes
A special thanks goes to @aerouk for almost all of the changes found here.
2013-12-15 01:09:18 -05:00
Wesley Wolfe
ad1f1c2c75 Add Location.setDirection(Vector). Adds BUKKIT-4862
This commit adds an additional method to Location to set the direction of
facing. Included are a set of unit tests that ensure the consistency of
getDirection and setDirection using a set of cardinal directions and
arbituary data points.

Javadocs were also added to pitch and yaw methods that explain the unit
and points of origin.
2013-12-11 03:42:13 -06:00
feildmaster
bd80c6eb2d Cleanup of c00ac08514 2013-12-09 16:25:03 -06:00
t00thpick1
c00ac08514 [Bleeding] Update MapPalette with new colors. Fixes BUKKIT-5094
As of Minecraft 1.7, there are 143 available map colors, MapPalette
needs to be updated to reflect the new colors.

This commit fixes the issue by adding the new colors to the
color matching array, and appropriately adjusts the color matching
methods as well.
2013-12-08 23:43:00 -06:00
LordRalex
f01d64b538 Add detonate method for firework entities. Adds BUKKIT-4538
This commit adds a method on fireworks that allows them to explode as
if their fuse ran out.
2013-12-06 00:10:51 -06:00
GJ
240579337b Add new fishing enchants. Fixes BUKKIT-5035 2013-12-04 21:17:31 -07:00
Wesley Wolfe
16b340dd38 Pulling all pending Bukkit-JavaDoc changes 2013-11-30 21:14:02 -06:00
mbax
1db19b62db Update Update Bukkit to 1.7.2 2013-11-30 19:01:48 -06:00
EvilSeph
b9846e5de4 Updated version to 1.6.4-R2.1-SNAPSHOT for development towards next release. 2013-10-30 19:44:21 -04:00
EvilSeph
03f18475c2 Updated version to 1.6.4-R2.0 in pom.xml for RB. 2013-10-30 19:22:05 -04:00
EvilSeph
92d0125e7f Updated version to 1.6.4-R1.1-SNAPSHOT for development towards next release. 2013-10-24 02:28:08 -04:00
EvilSeph
d92d26a38e Updated version to 1.6.4-R1.0 in pom.xml for RB. 2013-10-24 01:50:00 -04:00
Luke A
b7eaa4a13f Display command-message closing bracket correctly. Fixes BUKKIT-4894
This commit adds proper formatting to the closing bracket used when certain
commands send messages to all players with the broadcast-channel
permission.
2013-10-19 20:41:00 -05:00
Wesley Wolfe
0195253083 Fix format of 9cba5ff2b8 2013-10-15 04:17:30 -05:00
Wesley Wolfe
9cba5ff2b8 Update maven compiler to 2.3.2
This change removes a redundant addition of source encoding and makes our
compiler match the current maven default. This amends the commit
52215c6171

Upstream issue http://jira.codehaus.org/browse/MCOMPILER-70
2013-10-15 04:07:40 -05:00
Wesley Wolfe
0a100eb732 Use simple multiplication for squaring. Fixes BUKKIT-4836
This change adds a method to NumberConversions for squaring and
replaces uses of Math.pow(..., 2) with the new method for efficiency
reasons.
2013-10-09 01:56:35 -05:00
feildmaster
9296ebf83b Actually display correct effect duration in seconds. Fixes BUKKIT-3983 2013-09-23 13:19:00 -05:00
Joe
7ab753599a Display correct effect duration in seconds. Fixes BUKKIT-3983 2013-09-23 12:59:02 -05:00
feildmaster
13add0250e Update Bukkit to 1.6.4 2013-09-19 13:24:36 -05:00
Wesley Wolfe
30a9411199 Correct some magic values. This amends 1f83111208 2013-09-11 02:17:22 -05:00
EvilSeph
d7f00eea09 Updated version to 1.6.2-R1.1-SNAPSHOT for development towards next release. 2013-09-11 00:54:50 -04:00
EvilSeph
d0d5d515b6 Updated version to 1.6.2-R1.0 in pom.xml for RB. 2013-09-10 22:37:12 -04:00
feildmaster
85ae689084 Add missing villager sounds. Addresses BUKKIT-4756 2013-09-10 21:30:15 -05:00
EvilSeph
26038cefd3 Add SpawnReason for Entity Reinforcements. Fixes BUKKIT-4744 2013-09-10 22:24:07 -04:00
Wesley Wolfe
6d03f7a638 Pulling all pending Bukkit-JavaDoc changes 2013-09-10 21:02:53 -05:00
Phillip Schichtel
6ae876a38c Add support for command tab completion in the console. Adds BUKKIT-4168
This commit corrects tab-completion logic to consider non-player command
senders.
2013-09-10 20:58:23 -05:00
Kezz101
eaf0265f5b Update /say to vanilla behaviour. Fixes BUKKIT-4224
Prior to this commit all /say command output would be a generic "[Server]"
prefixed line. This commit changes that by adding the source into the
message, such as a player. By doing this Bukkit more closely matches
vanilla behaviour and gives a more descriptive message to the client.
2013-09-10 19:40:03 -06:00
feildmaster
22a61ef7f0 Add new sounds to the Sound Enum. Addresses BUKKIT-4756 2013-09-10 20:23:58 -05:00
feildmaster
fcd62eec61 Make /spreadplayers command work. Fixes BUKKIT-4720 2013-09-09 20:03:15 -05:00
Wesley Wolfe
1f83111208 Deprecate magic values 2013-08-28 01:44:09 -05:00
Wesley Wolfe
52215c6171 Add source encoding to the maven compiler plugin.
This change adds the source encoding to the maven compiler plugin, which
will strictly enforce build consistency on multiple platforms and address
possible compilation issues on some of the source files. The source
encoding unintuitively is system-specified by default.
2013-08-28 01:41:53 -05:00
Kane York
47ef04fe48 Use command block's world for /gamerule. Fixes BUKKIT-3274
In vanilla, gamerules are global, across all worlds. Maps created for
vanilla that use command blocks expect this behavior, which is broken
when they are placed on a world that is not the default world (world #0).

This commit changes that by using the command block's current world when
executing the command, forcing the game rules executed to be executed in
the world the command block is currently in.
2013-08-21 00:08:50 -06:00
ST-DDT
91d0f8ba57 Fix missing closing bracket in addEnchantment. Fixes BUKKIT-4126
Prior to this commit the message would display as "...(given #, bounds
are # to #". This commit changes that by adding the missing bracket to
the end of the statement. This is strictly a visual error.
2013-08-20 23:55:32 -06:00
Peter Olson
b4980840ab Add missing materials to Step. Fixes BUKKIT-4074
When Minecraft 1.4.6 was released, Nether Brick texturing to steps
was added. Minecraft 1.5 added Quartz texturing to steps. When Bukkit
was updated to these version the textures for steps were not applied.

Currently it is not possible to set the texture of steps to quartz
or nether brick. This commit fixes that by adding the respective values
to the allowable materials list.
2013-08-17 18:34:50 -06:00
AlphaBlend
bb628f80d7 Check null before grabbing metadata owning plugin. Fixes BUKKIT-4665
MetadataStoreBase throws a NullPointerException when passed a null value
for setMetaData. The intended behavior is to throw an
IllegalArgumentException. This commit changes the value's null check to
occur before referencing the owning plugin of a value.
2013-08-07 02:26:10 -05:00
Score_Under
e7f3d55221 [BREAKING] Use event class instead of event for timings. Fixes BUKKIT-4664
TimedRegisteredListener uses a reference to the first event fired. This
causes a memory leak in the server for any references that event has. This
changes TimedRegisteredListener to only store a reference to the class of
the event.

This change is intentionally a breaking change, as it is an obscure part
of the API. A non-breaking change would require the leak to be maintained
or an immediate update for any plugins using the method, as it would be an
indirect break.

A unit test is also included to check behavior of shared superclass
functionality.
2013-08-07 02:04:31 -05:00
Wesley Wolfe
ca47bf17e3 Add ConfigurationSerializable-Serializable compatibility. Adds BUKKIT-4662
This commit adds a comaptibility layer for use between
ConfigurationSerializable and Java Serializable, such that when using the
Bukkit object streams, any ConfigurationSerializable acts as if it
implements Serializable for purposes of that wrapped stream.

Included are a set of unit tests for the stream with a check for backward
compatibility across versions.
2013-08-06 18:19:15 -05:00
Wesley Wolfe
1d8e53cc2c Relax generic types for ConfigurationSerialization
The method signatures are unnecessarily strict for the generic signatures.
This change may cause a compile-time error for extending classes overriding
methods, but no byte signature or compile time call signatures change.
2013-08-06 18:19:15 -05:00
EvilSeph
f62a875770 Updated version to 1.6.2-R0.2-SNAPSHOT for development towards next release. 2013-08-04 00:44:08 -04:00
EvilSeph
42c4978d42 Updated version to 1.6.2-R0.1 in pom.xml for Beta. 2013-08-03 21:50:35 -04:00
Edmond Poon
466febbe41 Pulling all pending Bukkit-JavaDoc changes 2013-08-03 21:46:30 -04:00
Wesley Wolfe
2ccd6714a1 Use player as point of reference for min volume. Fixes BUKKIT-4640
When the minimum volume is being used because the distance is over a
threshold, the unit vector delta should be added to the player's
location, instead of where the command specified location.

This change makes the player's location the point of reference for
playing sounds when distance to volume scale is lower than minimum
specified volume.
2013-08-03 18:26:31 -05:00
T00thpick1
bf832ee9d6 Add leash API. Adds BUKKIT-4459 and BUKKIT-4583 2013-08-03 15:05:34 -05:00
Wesley Wolfe
02f2b5e290 Account for relative coordinates in PlaySound. Fixes BUKKIT-4639 2013-08-02 20:26:55 -05:00
h31ix
d789396b2d Add 1.6 effect clear functionality. Fixes BUKKIT-4473 2013-08-02 15:49:08 -05:00
h31ix
7f67959c24 Add 1.6 SpreadPlayers command. Fixes BUKKIT-4508 2013-08-02 15:38:55 -05:00
h31ix
dd0aa63021 Add 1.6 PlaySound command. Fixes BUKKIT-4489 2013-08-02 00:09:46 -05:00
T00thpick1
08c71f24ab Add API to control scaled health. Adds BUKKIT-4590 2013-07-21 20:18:08 -05:00
EvilSeph
f638ec1bfb Minecraft spec has changed and we're required to follow. We now build with Java 6. 2013-07-10 19:33:47 -04:00
h31ix
1a8fb592da Add Horse API. Adds BUKKIT-4424
API has been added to interface with Horses and to modify their inventories. A new event, HorseJumpEvent, has been added to be fired whenever a horse jumps.

This commit fixes BUKKIT-4393.
2013-07-10 12:18:45 -04:00
Nate Mortensen
a70ffc5519 Update Bukkit for Minecraft 1.6.2 2013-07-08 20:00:58 -04:00
Wesley Wolfe
dd745127a2 Add scale health display API. Adds BUKKIT-4432 2013-07-03 01:15:53 -05:00
Wesley Wolfe
1343ffa3ad Update Bukkit for Minecraft 1.6.1 2013-07-01 05:50:24 -05:00
EvilSeph
b67b640449 Updated version to 1.5.2-R1.1-SNAPSHOT for development towards next release. 2013-06-14 22:25:39 -04:00
EvilSeph
3d935f2b7e Updated version to 1.5.2-R1.0 in pom.xml for RB. 2013-06-14 21:52:51 -04:00
Des Herriott
373af3e9af Add PlayerBookEditEvent. Adds BUKKIT-1995
Event related to book & quill and written book items.
2013-06-10 10:55:51 -06:00
mbax
cbd5e3bfe5 Consider full team display name. Fixes BUKKIT-4186
Through a miscalculation, team display names were being created via
command ignoring the first word in the submitted display names.
2013-06-05 19:43:25 -05:00
riking
cd0205e53e Improve events for new inventory features. Adds BUKKIT-3859
This commit brings the InventoryClickEvent up to date with the new Minecraft
changes in 1.5.

InventoryDragEvent (thanks to @YLivay for his PR) is added to represent the
new "dragging" or "painting" functionality, where if you hold an itemstack and
click-drag over several slots, the items will be split evenly (left click) or
1 each (right click).

The ClickType enum is used to represent what the client did to trigger the
event.

The InventoryAction enum is reserved for future expansion, but will be used to
indicate the approximate result of the action.

Additionally, handling of creative inventory editing is improved with the new
InventoryCreativeEvent, and handling of numberkey presses is also improved
within InventoryClickEvent and CraftItemEvent.

Also, cancelling a creative click now displays properly on the client.

Adresses BUKKIT-3692, BUKKIT-4035, BUKKIT-3859 (new 1.5 events),
BUKKIT-2659, BUKKIT-3043, BUKKIT-2659, and BUKKIT-2897 (creative click events).
2013-06-03 17:57:14 -06:00
Wesley Wolfe
faea684c23 Pulling all pending Bukkit-JavaDoc changes 2013-05-16 04:41:09 -05:00
EvilSeph
e290523e51 Updated version to 1.5.2-R0.2-SNAPSHOT for development towards next release. 2013-05-03 18:39:18 -04:00
EvilSeph
840d5a97a8 Updated version to 1.5.2-R0.1 in pom.xml for BETA. 2013-05-03 17:42:51 -04:00
Score_Under
056ce5b046 Move world generator warning to CraftBukkit. Fixes BUKKIT-2565 2013-04-30 17:07:48 -07:00
Travis Watkins
e9a122bd3c Update Bukkit for Minecraft 1.5.2 2013-04-27 02:30:07 -05:00
Peter Olson
14f1de7244 Add inverted flag support to TrapDoor. Fixes BUKKIT-3390 2013-04-18 17:21:12 -07:00
EvilSeph
339554099f Updated version to 1.5.1-R0.3-SNAPSHOT for development towards next release. 2013-04-13 02:58:22 -04:00
EvilSeph
01aabbb034 Updated version to 1.5.1-R0.2 in pom.xml for BETA. 2013-04-13 02:47:03 -04:00
Wesley Wolfe
f569209ef8 Pulling all pending Bukkit-JavaDoc changes 2013-04-13 01:36:32 -05:00
Acrobot
2de99a4f38 Fix off-by-one error in DyeColor. Fixes BUKKIT-3938 2013-04-12 18:27:41 -07:00
Travis Watkins
30a975890e Correct 1.5 material data. Fixes BUKKIT-4004, BUKKIT-3785 2013-04-12 16:20:50 -05:00
Wesley Wolfe
18c46487ad Consider first player name in leave command. Fixes BUKKIT-4051 2013-04-11 22:56:31 -05:00
Wesley Wolfe
be1429665d Consider arguments to team leave properly. Fixes BUKKIT-3994
Two checks to argument length were changed to properly consider if the
sender is a player instead of an off-by-one logical error.
2013-04-05 12:49:59 -05:00
Wesley Wolfe
5ca534dc9b Use utility method for team-join display. Fixes BUKKIT-3997
The method to make a string from a collection of strings already exists
and should be used when adding multiple players to a team.
2013-04-05 12:40:03 -05:00
crast
410bd305b8 Prevent classloader leak in metadata system. Fixes BUKKIT-3854
Metadata values keep strong reference to plugins and they are not
cleared out when plugins are unloaded. This system adds weak reference
logic to allow these values to fall out of scope. In addition we get
some operations turning to O(1) "for free."
2013-04-04 14:02:53 -05:00
crast
b7a9cd9d41 Don't cache metadata store disambiguations. Fixes BUKKIT-3841
The metadata system generates unique keys for metadata entries based on
the subject metadata is being applied to and the name of the metadata
being applied. It was assumed this would be an expensive operation so a
cache was put in place to ensure this was done as little as possible.

In reality this cache only has a benefit when you have a hit rate above
~90% and is otherwise much slower. As the implementation of the cache is
a hashmap of hashmaps it also uses a significant amount of memory which
is not worth it even for the performance increase with a high hit rate.

This commit simply removes the cache which results in speedups for most
cases and large memory savings.
2013-04-04 13:43:33 -05:00
crast
771c5bdfaa Improve speed and memory use of FixedMetadataValue. Fixes BUKKIT-1460
FixedMetadataValue currently just extends LazyMetadataValue with a value
that never changes. While this works it is a lot of unneeded overhead
that causes FixedMetadataValue to be a lot slower and use a lot more
memory than one would expect. To correct this we store the value directly
in FixedMetadataValue and override the the appropriate methods to use it.

Ideally we would modify FixedMetadataValue to no longer extend
LazyMetadataValue as this would give a very large memory savings. However,
this is not currently done for backwards compatibility reasons.
2013-04-04 13:27:06 -05:00
crast
4d2e3d704d Refactor common metadata code into base class. Fixes BUKKIT-3624
Implementing the MetadataValue interface is significant work due to
having to provide a large amount of conversion stub methods. This commit
adds a new optional abstract base class to aid in implementation.
2013-04-04 13:20:17 -05:00
mbax
6fb1647394 Add Scoreboard API and Command. Adds BUKKIT-3776, BUKKIT-3834
The implementation is designed around having both a main scoreboard and
numberous plugin managed scoreboards that can be displayed to specific
players.

Plugin managed scoreboards are active so long as a reference is kept by a
plugin, or it has been registered as a player's active scoreboard. Objects
specific to a scoreboard remain active until unregistered (which remove a
reference to the owning scoreboard), but quickly fail if accessed
post-unregistration.
2013-04-03 23:32:54 -05:00
EvilSeph
faa386ae6a Updated version to 1.5.1-R0.2-SNAPSHOT for development towards next release. 2013-04-04 00:18:40 -04:00
EvilSeph
f706d57498 Updated version to 1.5.1-R0.1 in pom.xml for BETA. 2013-04-03 22:39:56 -04:00
Edmond Poon
409595c2a2 Pulling all pending Bukkit-JavaDoc changes 2013-04-02 00:11:22 -04:00
computerdude5000
10c1edca78 Ignore all .DS_Store files, not just root folder 2013-04-01 12:55:36 -07:00
feildmaster
9e614c1b0e Add Effect command. Adds BUKKIT-3763 2013-03-31 19:33:05 -05:00
Travis Watkins
7c8d3d4007 Add method to update state without physics update. Addresses BUKKIT-3939 2013-03-31 19:16:53 -05:00
Travis Watkins
f30d89ab33 Add Beacon BlockState for hopper events. Fixes BUKKIT-3932 2013-03-29 22:25:41 -05:00
Edmond Poon
ced8459bc3 Pulling all pending Bukkit-JavaDoc changes 2013-03-27 21:12:08 -04:00
Andre LeBlanc
c84d619368 Allow fishing success rate to be adjustable. Adds BUKKIT-3837 2013-03-25 14:44:01 -04:00
GJ
c8d2dcf6e2 Add methods to check for conflicting enchantments. Adds BUKKIT-3830 2013-03-25 07:55:59 -04:00
Patrick Seidel
9a0cafe031 Add ability to change player item in hand. Adds BUKKIT-3318 2013-03-24 13:59:27 -04:00
riking
db1a15f544 Add Thorns to DamageCause - Related to BUKKIT-3505 2013-03-23 19:43:05 -07:00
Dennis Bliefernicht
34239aeef2 Add InventoryMoveItemEvent. Adds BUKKIT-3765
This event is being called whenever a block or entity (e.g. hopper) tries to
move an item from one inventory to another inventory (one inventory may be
the hopper itself).
2013-03-23 16:11:39 -06:00
Xephi
46234ff555 Add Dropper BlockState. Adds BUKKIT-3750 2013-03-21 21:43:28 -06:00
Travis Watkins
34648c5d00 Map old wildcard recipe data to new 1.5 value. Fixes BUKKIT-3849 2013-03-21 21:10:23 -05:00
Olof Larsson
f62fbdb34c Add ability to modify ThrownPotion properties. Adds BUKKIT-3197 2013-03-21 15:17:31 -04:00
AlphaBlend
62cc82ac8f Add method to get the source of a TNTPrimed. Adds BUKKIT-3815 2013-03-21 12:48:53 -06:00
Andre LeBlanc
e4163622e3 Add Fish (Hook) entity to PlayerFishEvent. Adds BUKKIT-1025 2013-03-20 16:02:15 -07:00
nitnelave
d5caa86741 Added the hasGravity method to Blocks. Adds BUKKIT-3832 2013-03-20 18:49:25 -04:00
Travis Watkins
3d44b71712 Update Bukkit for Minecraft 1.5.1 2013-03-20 15:08:45 -05:00
Edmond Poon
ca7687d4f2 Pulling all pending Bukkit-JavaDoc changes 2013-03-20 00:42:05 -04:00
Nate Mortensen
9515adffff BlockState for Command Blocks. Adds BUKKIT-3805. 2013-03-19 20:51:03 -06:00
GJ
ad0ccaeddd Add an enum for Nether Wart growth stages. Adds BUKKIT-1599 2013-03-19 02:21:18 -04:00
Warren
f2135363c5 Remove point about squashing commits. 2013-03-18 23:49:02 -03:00
EvilSeph
907c8e8e7f Add missing new line to README.md 2013-03-18 22:35:10 -04:00
EvilSeph
32955452c6 Add link to CONTRIBUTING.md in README 2013-03-18 22:31:42 -04:00
EvilSeph
5ce29c1432 Pull Contributing Guidelines and Requirements into CONTRIBUTING.md 2013-03-18 22:16:30 -04:00
Travis Watkins
8846f9ec4c Add dummy /testfor command in Bukkit. Addresses BUKKIT-3813
This command only functions in command blocks so the bukkit command for it
simply spits out an error message.
2013-03-18 17:10:52 -05:00
T00thpick1
4a23f3f2d0 Add per-player Weather API. Adds BUKKIT-812 2013-03-18 13:09:11 -05:00
Yariv Livay
987aa600c4 Add block or entity causes to BlockIgniteEvent. Addresses BUKKIT-3609, BUKKIT-3656, BUKKIT-3657 2013-03-18 13:09:11 -05:00
Michael Limiero
33da518ab9 Add InventoryPickupItemEvent. Adds BUKKIT-3798 2013-03-18 13:09:04 -05:00
Michael Limiero
3091c16621 Make HopperMinecart implement InventoryHolder. Adds BUKKIT-3796 2013-03-18 12:13:28 -05:00
Travis Watkins
51798af209 No @Override here in Java 1.5. 2013-03-17 22:29:05 -05:00
Chad Waters
be85e48979 Add Entity.isOnGround(). Adds BUKKIT-3787 2013-03-17 22:24:22 -05:00
Travis Watkins
51da39dd27 Don't use deprecated interface. 2013-03-17 13:05:10 -05:00
Michael Limiero
de55f86844 Add Hopper block state and inventory type. Adds BUKKIT-3749 2013-03-17 12:57:47 -05:00
feildmaster
78bf7a911d Validate method parameters when registering events. Fixes BUKKIT-3779 2013-03-16 17:27:42 -05:00
Wesley Wolfe
3645b38ea5 Moved all specific minecart entities to sub-package.
This change is breaking for the new API for 1.5, including the interfaces for
the three new Minecart types and the name of the previously TNT_MINECART
material.

This change also deprecates the two previous specific minecart types located
in the org.bukkit.entity package. This deprecation is not a breaking change
and will still be internally supported.

Each minecart type has new javadoc to be slightly more descriptive. Included
with this are specific references to the interface for each respective
EntityType entry. Another package-info.java file has been included as well.

All specific minecart types extend minecart, each with a more descriptive
name. The naming will also follow the old convention. In addition, the
minecart with no specific designation is now more closely referred to as a
rideable minecart.
2013-03-16 02:30:31 -05:00
Travis Watkins
f9917ef1c6 Use proper naming convention for boolean methods. 2013-03-15 14:25:18 -05:00
Travis Watkins
9b0ecdfc76 Update Bukkit for Minecraft 1.5 2013-03-15 13:26:46 -05:00
Jeffrey Wardian
6ea916295b Removed superfluous recalculation call; Fixes BUKKIT-3728
The permission attachment interface provides two methods each for setting
and unsetting permissions. Each one also provides an extra call to the
recalculatePermissions() method on the permissible, which degrades
performance.

This commit removes the duplicate call to recalculate permissions.
2013-03-12 01:07:26 -07:00
Max A
bcedb6be85 Convert name to lower case for removePermission; Fixes BUKKIT-3726
Permissions are stored as lower case names and referenced as such in all
appropriate methods but removePermission. This changes removePermission
to also convert names to lower case to be consistent with the rest of
the API.
2013-03-11 02:48:56 -07:00
EdGruberman
eae344b1e0 Test PluginManager.removePermission
Static methods are death to testability.  However, irrelevant static
methods can be negotiated with until a later time in which they can be
removed.  When instantiating a new Permission object, static calls are
made to the Bukkit class during a recalculatePermissibles logic path.
This recalculatePermissibles call should probably be moved
appropriately, but until the time such testing can be accomplished
itself, these tests work around that situation by simply verifying the
static Bukkit server references are satisfied since what is called as
a result is irrelevant currently.

This commit also updates a few other tests for PluginManagerTest to
work towards the standard of using the Hamcrest unit testing library.
2013-03-11 02:48:56 -07:00
Travis Watkins
aa7469c71f Add PlayerItemConsumeEvent. Adds BUKKIT-2349 2013-03-02 00:03:57 -06:00
Wesley Wolfe
0b494f8896 Pulling all pending Bukkit-JavaDoc changes 2013-02-22 22:49:38 -06:00
Wesley Wolfe
23f5a057f8 Fix ClassCastException for malformed plugin.yml. Fixes BUKKIT-3563
If the plugin.yml gets loaded but wasn't in the form of a map, the
server would crash. This safely checks to see if it can be cast,
throwing invalid description if it cannot.
2013-02-03 04:08:10 -06:00
EvilSeph
f598dac9c8 Updated version to 1.4.7-R1.1-SNAPSHOT for development towards next release. 2013-01-30 23:44:29 -05:00
EvilSeph
91f59245e0 Updated version to 1.4.7-R1.0 in pom.xml for RB. 2013-01-30 23:32:04 -05:00
feildmaster
3fc631fd72 Fix invalid integers in spawnpoint command. Fixes BUKKIT-3509
getInteger returns min value on illegal number formats, so we change
behavior to throw an exception when requested.
2013-01-26 13:54:00 -06:00
EdGruberman
7f87d99353 Only use TravelAgent if supplied; Addresses BUKKIT-3466
If there is no TravelAgent assigned, it can not be used.
2013-01-24 04:05:49 -06:00
feildmaster
6eeaee4c38 Don't try listing something that may not exist. Fixes BUKKIT-3471
The player name may not be provided, in which case the command will
fail hard.
2013-01-23 05:51:46 -06:00
feildmaster
bbc75c4a68 Improve javadoc in 26 files.
Addresses:
BUKKIT-1643, BUKKIT-1868, BUKKIT-1846, BUKKIT-2632, BUKKIT-3196,
BUKKIT-3187, BUKKIT-3198, BUKKIT-3200, BUKKIT-3201 and BUKKIT-3417.
2013-01-22 16:41:00 -06:00
EdGruberman
127e74cb56 [Bleeding] Add experimental support for entity portal traveling
EntityPortalEvent is called when an entity is about to portal to a
new location. This event is cancellable on top of being able to
change the exit location.

EntityPortalExitEvent is called when exiting the portal, allowing
for adjustment of the exit velocity.
2013-01-19 06:06:22 -06:00
EvilSeph
91d9b246b8 Updated version to 1.4.7-R0.2-SNAPSHOT for development towards next release. 2013-01-17 05:30:30 -05:00
EvilSeph
76d0a6702d Updated version to 1.4.7-R0.1 in pom.xml for Beta. 2013-01-17 05:15:55 -05:00
feildmaster
430e30ee9c Update Bukkit to Minecraft 1.4.7 2013-01-17 01:42:56 -06:00
MikeMatrix
a91c4c6f38 Added negative id check to Material.getMaterial(int). Fixes BUKKIT-3414
Negative id values would try to access the array out of bounds and throw an java.lang.ArrayIndexOutOfBoundsException.
2013-01-15 05:05:20 -06:00
Wesley Wolfe
2877472d92 Switch DyeColor firework Colors. Fixes BUKKIT-3382
The firework colors were based on the respective wool data values. This
means the colors were in reverse order.
2013-01-05 17:24:37 -06:00
Wesley Wolfe
f0dcb97476 Clarify dye and wool color datas in DyeColor. Addresses BUKKIT-2786
DyeColor used the wool data for getData(), which is very misleading based
on class name. The old method has been deprecated and replaced with
getWoolData() and getDyeData() for the appropriate types of data values.

The MaterialData classes Dye and Wool were updated appropriately,
especially Dye innapropriately using a DyeColor data value compensation.

Unit tests were added for the new methods, as well as the getColor on Dye
and Wool.
2013-01-05 17:20:39 -06:00
feildmaster
6f9e46c5a3 Add experience methods for PlayerFishEvent. Adds BUKKIT-3348 2013-01-01 23:44:18 -06:00
EvilSeph
7fe5c055a6 Updated version to 1.4.6-R0.4-SNAPSHOT for development towards next release. 2012-12-31 01:13:57 -05:00
EvilSeph
a725f738d6 Updated version to 1.4.6-R0.3 in pom.xml for Beta. 2012-12-31 01:00:11 -05:00
EvilSeph
fe8d790ac2 Updated version to 1.4.6-R0.3-SNAPSHOT for development towards next release. 2012-12-29 22:27:35 -05:00
EvilSeph
438e2dfded Updated version to 1.4.6-R0.2 in pom.xml for Beta. 2012-12-29 22:19:08 -05:00
feildmaster
307b99f3ee Don't allow nulls in PlayerRespawnEvent. Fixes BUKKIT-2571 2012-12-29 18:41:23 -06:00
Wesley Wolfe
a0ebffc4e0 Add method to get defult leather color. Adds BUKKIT-3203
The default leather color is already used internally in place of null. The
javadocs were updated appropriately to indicate as such.
2012-12-27 13:03:14 -06:00
Wesley Wolfe
584408ef46 Use correct warning in JavaPluginLoader. Fixes BUKKIT-3315
The warning message printed with the stack traces on the deprecated
methods mistakingly use the wrong method signature in the description.
2012-12-27 13:02:40 -06:00
Luke GB
3f706a658a Fix menus for relative pathing.
This fixes the Maven generated site so the paths are relative. This is
required so that multiple generations of the javadocs can be hosted at once,
and so no cross-linking occurs.
2012-12-23 15:45:28 -06:00
feildmaster
0f92972fe2 Add methods to set and reset max health. Adds BUKKIT-266 2012-12-23 07:28:37 -06:00
Travis Watkins
601df7d25f Remove duplicate message for console. Fixes BUKKIT-3267 2012-12-23 02:33:25 -06:00
EvilSeph
f7ae711b6f Updated version to 1.4.6-R0.2-SNAPSHOT for development towards next release. 2012-12-22 01:24:01 -05:00
EvilSeph
adf090165f Updated version to 1.4.6-R0.1 in pom.xml for Beta. 2012-12-22 01:12:03 -05:00
feildmaster
505d128c50 Add firework api to get and set Firework ItemMeta 2012-12-21 23:55:02 -06:00
meiskam
bc73b59d27 Add Skull BlockState and Type enum. Adds BUKKIT-3258 2012-12-21 22:24:50 -06:00
Wesley Wolfe
4769661a51 Add enchantment storage meta. Adds BUKKIT-3237
Books can 'store' enchantments that can be applied to other items later.
These enchantments exist seperately of enchantments that actually effect the
item, and are as stated 'stored' in the book instead of the book being
enchanted. The meta is generically named as the concept could be applied to
other item types later, such as a enchantment scroll.

All of the methods mimic those in the base meta, but instead specify
'stored' in each method name.
2012-12-21 10:36:17 -06:00
Wesley Wolfe
b119513428 Add FireworkEffect and respective item metas. Adds BUKKIT-3236
FireworkEffect is an immutable class that requires the builder pattern
to construct, to reduce ambiguity and help make code uses more readable.

FireworkMeta contains a list of effects, as well as a flight height.

FireworkEffectMeta contains a single effect for charges.
2012-12-21 10:36:07 -06:00
Wojciech Stryjewski
73cabfbd0f Add API to allow plugins to request players switch to a texture pack. Adds BUKKIT-2579
The setTexturePack method causes the player's client to
download and switch to a texture pack specified by a URL.

Note: Players can disable server textures on their client, in which
case this API would not affect them.
2012-12-20 22:20:56 -05:00
feildmaster
70b440e189 Update Bukkit to Minecraft 1.4.6 2012-12-20 11:26:32 -06:00
EvilSeph
1e4373dc34 Updated version to 1.4.5-R1.1-SNAPSHOT for development towards next release. 2012-12-19 06:15:29 -05:00
EvilSeph
8189f9e04b Updated version to 1.4.5-R1.0 in pom.xml for RB. 2012-12-19 06:07:57 -05:00
feildmaster
c8150a3428 Apply commandBlockOutput to broadcastMessage. Addresses BUKKIT-3117 2012-12-18 04:47:56 -06:00
feildmaster
04e2483b71 Refactor get/setChestPlate to Chestplate. Addresses BUKKIT-3189
This method was inconsistent with previous methods.
2012-12-18 03:46:45 -06:00
feildmaster
ff1ff5d968 Fix MaterialData directions being incorrect. Fixes BUKKIT-3160
Prior to 49690f9, BlockFaces were mostly correct in their respective
MaterialData classes. However, a lot of things were not updated since
implementation and broke without being addressed.

This fixes any discrepancies with Block data.
2012-12-18 03:25:00 -06:00
Wesley Wolfe
203de4180b Deprecate methods in JavaPluginLoader and PluginClassLoader
These methods are unnecessarily exposed. They are specific to a type of
implementation for the class loaders, and should have no external use.
Because these methods are exposed, it limits the versatility to change
how the internal class loading system works, including an inherent class
loader leak for some situations.

They are now replaced with internal, package-private methods. The public
facing methods will print a stack trace the first time one is activated.

Extending the classes also produces a stack trace, to indicate that
extension is not actively supported.
2012-12-18 00:15:40 -06:00
Wesley Wolfe
7c15e71ef9 Clarify functionality in Inventory. Fixes BUKKIT-3097
Mainly javadoc changes to be specific in functionality and outcomes. This is
mixed with specifying that null Material should throw IllegalArgumentException
instead of the previous undefined NullPointerException.

Included is a clarification on how contains(ItemStack, int) works, and a new
method containsAtLeast(ItemStack, int) for counting the number of a specific
item.
2012-12-17 16:49:12 -06:00
Wesley Wolfe
a06f7b1b86 Add ItemMeta factory and interfaces. This adds BUKKIT-15
Included with ItemMeta is a new serializable class Color.

PotionEffects are now serializable.
2012-12-17 01:16:28 -06:00
Wesley Wolfe
a7bd98960a Add Material methods. Adds BUKKIT-3161, BUKKIT-3162, BUKKIT-3163,
BUKKIT-3164

This adds an isFlammable method, to indicate if a block can catch fire.

This adds an isTransparent method, to check if light can pass through.

This adds an isOccluding method, to check if it fully blocks vision.

This adds an isBurnable method, to indicate if a block can burn away.
2012-12-14 02:03:05 -06:00
feildmaster
5d6592e5d2 Add EntityEquipment API. Adds BUKKIT-3103 2012-12-10 19:09:58 -06:00
Wesley Wolfe
428b2e9390 Bump JUnit version 2012-12-09 18:14:54 -06:00
Wesley Wolfe
8b669c18b2 Add isSolid() to Material. Adds BUKKIT-3131
A 'solid' material indicates that it is a block and cannot be passed
through.
2012-12-09 15:13:25 -06:00
feildmaster
f3dfe8bd01 An executor set to null will now use the plugin. Fixes BUKKIT-3127 2012-12-09 00:31:25 -06:00
feildmaster
8df7caf91f Add FurnaceExtractEvent. Addresses BUKKIT-2114
Added a "BlockExpEvent" to hold experience and the handlers for the events
2012-12-09 00:31:23 -06:00
Travis Watkins
0700565d8b Provide a faster way to get a location. Adds BUKKIT-3120
Currently when a plugin wants to get the location of something it calls
getLocation() which returns a new Location object. In some scenarios this
can cause enough object creation/destruction churn to be a significant
overhead. For this cases we add a method that updates a provided Location
object so there is no object creation done. This allows well written code
to work on several locations with only a single Location object getting
created.

Providing a more efficient way to set a location was also looked at but
the current solution is the fastest we can provide. You are not required
to create a new Location object every time you want to set something's
location so, with proper design, you can set locations with only a single
Location object being created.
2012-12-07 21:18:31 -06:00
feildmaster
089ab8e525 Add API to get and set collar colors of wolves 2012-12-05 18:03:24 -06:00
Wesley Wolfe
d9dc8fce62 Deprecate the scheduleAsync methods.
The name is misleading, as it can be misconstrued to mean "a sync"
instead of properly understanding it as "an async"
2012-12-05 13:18:47 -06:00
feildmaster
74a6fb9834 Add getShutdownMessage() and stop command arguments. Adds BUKKIT-3031 2012-12-05 06:06:44 -06:00
Wesley Wolfe
e468a8b391 [BREAKING] EntityChangeBlockEvent can be non-living. Adds BUKKIT-3078
Non-living entities can change blocks, specifically falling blocks. This change is a small source break, but mainly a byte-code break (requires plugins to recompile).
2012-12-04 22:17:03 -06:00
Travis Watkins
f5a0cf0821 Add API for controlling mob despawn away from players. Adds BUKKIT-2986 2012-12-04 21:30:44 -06:00
feildmaster
49690f9620 [BREAKING] Update BlockFace directions. Fixes BUKKIT-1567, BUKKIT-3069
If you use BlockFace in any way, to compensate the directionals being incorrect, you can still have backwards compatibility if you add in the handling in your plugin:
boolean legacyBlockFace = BlockFace.NORTH().getModX() == -1; (and then handle it accordingly)

If you didn't special case your directions to fix what's being fixed here... Hurray! Your plugin should now work.
2012-12-01 01:06:29 -06:00
Wesley Wolfe
4272e10fb7 Add data values for entity change block event. Adds BUKKIT-3077, BUKKIT-3076 2012-11-30 12:07:10 -06:00
feildmaster
1736f766dc Add API for creating explosions without damaging blocks. Fixes BUKKIT-3061 2012-11-27 19:35:03 -06:00
Wesley Wolfe
5165d9657e Make RECORD_12 a record. Fixes BUKKIT-3023
Record 12 was missed when added to the Material enum.
2012-11-24 02:26:07 -06:00
Darth Android
b0b6d082d9 Cache material data constructors. Fixes BUKKIT-2980
Reobtaining a constructor is not a trivial operation, this change makes the Material enum store the respective constructors for each MaterialData.

Additionally 'fixed' the material tests to use proper generics.
2012-11-24 02:25:20 -06:00
EvilSeph
ec2ad0f387 Updated version to 1.4.5-R0.3-SNAPSHOT for development towards next release. 2012-11-20 20:34:06 -05:00
EvilSeph
d09e7cc69d Updated version to 1.4.5-R0.2 in pom.xml for Beta. 2012-11-20 20:06:15 -05:00
feildmaster
e31418234f Add DamageCause for FallingBlocks. Adds BUKKIT-2781 2012-11-20 17:09:25 -06:00
EvilSeph
9470616030 Updated version to 1.4.5-R0.2-SNAPSHOT for development towards next release. 2012-11-18 22:50:48 -05:00
EvilSeph
bc856644b0 Updated version to 1.4.5-R0.1 in pom.xml for Beta. 2012-11-18 22:39:58 -05:00
EvilSeph
288ec65421 Add ability to pass 'max' as 'level' for EnchantCommand. 2012-11-18 17:45:00 -05:00
Karl Fritsche
872851890a Update sounds for Minecraft 1.4.2 changes. Fixes BUKKIT-2849 2012-11-17 11:07:49 -06:00
James Clarke
95f68e9d36 Add API for getting and setting Skeleton and Zombie types. Fixes BUKKIT-2818 2012-11-17 10:05:53 -06:00
EvilSeph
ea864fbaf7 Add default EnchantCommand. Tim, The Enchanter - I AM DEATH! Adds BUKKIT-2961 2012-11-17 01:14:41 -05:00
EvilSeph
f3468327b9 Essential core commands shouldn't be overriden. Fixes BUKKIT-1546 2012-11-17 00:27:36 -05:00
Travis Watkins
be36f8114e Update Bukkit for Minecraft 1.4.5 changes. 2012-11-16 10:12:54 -06:00
EvilSeph
9421e618b9 Add aliases to TellCommand to bring us in line with Vanilla behaviour. 2012-11-15 23:04:45 -05:00
EvilSeph
d31ca9e797 Remove unnecessary Overrides in Default commands. 2012-11-15 23:03:03 -05:00
EvilSeph
b2870e185a Made KillCommand set the player health to 0 to allow it to work in Creative. Fixes BUKKIT-2949 2012-11-15 22:52:10 -05:00
EvilSeph
50814db38a Added proper feedback to default commands. 2012-11-15 22:52:04 -05:00
Wesley Wolfe
5bc7c5ad89 Make some JavaPlugin methods final. Fixes BUKKIT-2916
These methods were never intended to be overwritten, and bukkit relies
on their internal functionality. Additionally, the methods were inlined
in JavaPlugin, but the finality maintains intention.
2012-11-13 16:13:45 -06:00
Travis Watkins
69374c7d40 Update Bukkit for Minecraft 1.4.4 changes. 2012-11-13 16:13:38 -06:00
EvilSeph
4b2401de76 Updated version to 1.4.2-R0.3-SNAPSHOT for development towards next release. 2012-11-03 01:08:00 -04:00
EvilSeph
a329871d2e Updated version to 1.4.2-R0.2 in pom.xml for Beta. 2012-11-03 00:50:26 -04:00
EvilSeph
e94003894b Add yaw and rotation to default TeleportCommand. Fixes BUKKIT-2774 2012-10-31 22:02:47 -04:00
EvilSeph
fb4bffac00 Updated version to 1.4.2-R0.2-SNAPSHOT for development towards next release. 2012-10-31 20:51:51 -04:00
EvilSeph
cbe6ec1b44 Updated version to 1.4.2-R0.1 in pom.xml for Beta. 2012-10-31 15:59:04 -04:00
EvilSeph
c6b29a7899 Add EXPLOSION and DEFAULT RemoveCauses to the HangingBreakEvent.
EXPLOSION is used when a hanging entity is removed by an explosion.
DEFAULT is used when a hanging entity is removed by an uncategorised
cause.
2012-10-31 14:23:56 -04:00
Travis Watkins
b077059192 Add inventory types for new containers. Fixes BUKKIT-2741 2012-10-31 13:25:26 -04:00
Travis Watkins
aa4644cda3 Add API for ambient mob spawn limit. Adds BUKKIT-2765 2012-10-31 13:01:29 -04:00
Travis Watkins
07ba841f34 Add BlockCommandSender for Command block 2012-10-31 10:54:53 -05:00
EvilSeph
d6d81089a1 Fixed typo in PotionType. 2012-10-31 11:40:11 -04:00
Wesley Wolfe
bacc2e3596 Replace 'Magic Numbers' in commands.
These numbers are mirrored in vanilla code as the coordinate limits for
a world. Replaced usages to a static final member for code readability.
2012-10-31 04:19:11 -05:00
Wesley Wolfe
276d45f1f0 Provide the 1.4.2 potions. Adds BUKKIT-2727.
Two potion types were missing from the 1.4.2 update. Invisibility and
night vision are now in the potion type enum.

Fixes an erroneous use of PotionEffectType.SPEED where it should have
been WEAKNESS.

Removed deprecation for the PotionEffectType relating to certain effects
that are now active in 1.4.2.

Fixes BUKKIT-2677, BUKKIT-2758.
2012-10-31 04:19:11 -05:00
feildmaster
5fb6a4f82b Add default GameRule command. Fixes BUKKIT-2671 2012-10-31 03:45:26 -04:00
feildmaster
482d5e3ee4 Add API for managing and using GameRules. Adds BUKKIT-2757 2012-10-31 03:44:26 -04:00
h31ix
ccd030487b Add API for ItemFrames. Adds BUKKIT-2668
As well as adding methods for ItemFrames, this moves some methods
previously contained in Painting to Hanging, as they are shared by both
classes.

An enum was added that represents rotations, similar to a clock-face.
This is needed as a contrast to cardinal direction based rotations.
2012-10-31 01:19:33 -05:00
h31ix
f3af02a53b [Bleeding] Add new events for Hanging entities, deprecate old Painting
events. Adds BUKKIT-2754
2012-10-31 00:21:04 -04:00
EvilSeph
d9fdd9084e Add default Clear command. Partially fixes BUKKIT-2671 2012-10-30 04:53:42 -04:00
EvilSeph
781b77ce52 Add clear inventory API to PlayerInventory with a successful count return. Adds BUKKIT-2745 2012-10-30 04:52:43 -04:00
EvilSeph
2bc78a82fe Revert "Clear" commit, was not meant to be pushed.
This reverts commit bdf5d326f5.
2012-10-30 02:50:38 -04:00
mbax
629f2e5c58 [Bleeding] Check for player validity in spawnpoint command. Fixes BUKKIT-2742 2012-10-30 02:11:14 -04:00
EvilSeph
bdf5d326f5 Clear 2012-10-30 01:18:01 -04:00
EvilSeph
b9dda28b5b Update ExpCommand with levels support. Fixes BUKKIT-2683 and partially fixes BUKKIT-2671 2012-10-29 23:18:18 -04:00
feildmaster
d2df73a75e Revert FIREBALL being renamed to LARGE_FIREBALL 2012-10-29 19:59:53 -05:00
EvilSeph
1bf5267f8a Add default SpawnpointCommand. Partially fixes BUKKIT-2671 2012-10-29 05:06:04 -04:00
EvilSeph
e899b06d4d Expose setBedSpawnLocation with force option. Adds BUKKIT-2709 2012-10-29 04:58:51 -04:00
EvilSeph
012b814619 Add default WeatherCommand. Partially fixes BUKKIT-2671 2012-10-29 02:48:40 -04:00
EvilSeph
3b2e425abd Remove invalid tab completions from DefaultGameModeCommand as player names are not an accepted parameter. 2012-10-29 02:12:07 -04:00
EvilSeph
05876e9042 Add default DifficultyCommand. Partially fixes BUKKIT-2671 2012-10-29 01:53:31 -04:00
EvilSeph
aedafb9acd Add isHardcore API to check if the server is in hardcore mode or not. Adds BUKKIT-2707 2012-10-29 01:45:08 -04:00
Travis Watkins
d5d1b41c02 Update Bukkit for Minecraft 1.4(.2) changes. 2012-10-27 22:15:59 -04:00
EvilSeph
6dfeff0591 Updated version to 1.3.2-R3.0 in pom.xml for RB. 2012-10-27 21:10:43 -04:00
Wesley Wolfe
7adaf4bb6b Override toString() method in Command
Overriding the toString() method provides more human-readable feedback
when a problem occurs, including the version of the plugin if
applicable.
2012-10-19 15:46:28 -05:00
EvilSeph
a4314b17b1 Updated version to 1.3.2-R2.1-SNAPSHOT for development towards next release. 2012-10-17 07:36:30 -04:00
EvilSeph
88f3722e96 Updated version to 1.3.2-R2.0 in pom.xml for RB. 2012-10-17 07:30:01 -04:00
Wesley Wolfe
859aab1fa3 Add a tab completion API for chat messages. Adds BUKKIT-2607
This implementation provides access to a (mutable) list and the base
message. Also provided is a convenience method for getting the last
'token' in the provided string.
2012-10-17 04:56:11 -05:00
Score_Under
ede3fd278d Add tab-completion API. Fixes BUKKIT-2181. Adds BUKKIT-2602
CommandMap contains a method that will auto-complete commands
appropriately. Before the first space, it searches for commands of which
the sender has permission. After the first space, it delegates to the
individual command.

Vanilla commands contain implementations to mimic vanilla
implementation. Exception would be give, that allows for name matching;
a feature we already allowed as part of the command is now supported for
auto-complete as well.

Plugin commands can get a tab completer set to delegate the completion
for. If no tab completer is set, it can check the executor to see if it
implements the tab completion interface. It will also attempt to chain
calls if null gets returned from these interfaces. Plugins also
implement the new TabCompleter interface, to add ease-of-use for plugin
developers, similar to the onCommand() method.

The default command implementation simply searches for player names.

To help facilitate command completion, a utility class was added with
two functions. One checks two strings, to see if the specified string
starts with (ignoring case) the second. The other method uses the first
to selectively copy elements from one collection to another.
2012-10-16 00:05:40 -05:00
Wesley Wolfe
02ab53f388 Deprecate PlayerPreLoginEvent. Addresses BUKKIT-2600
PlayerPreLoginEvent was originally implemented with the intention that
putting synchronized blocks on the plugin manager made it thread safe.
Unintentionally, this causes the event to be executed when a plugin
would otherwise expect no events to be firing. It is now deprecated.
2012-10-14 03:36:08 -05:00
Wesley Wolfe
2750276da3 Add simpler API for using the scheduler. Adds BUKKIT-836
The new methods return the actual task that gets created from the
scheduler. They are also named such that auto-complete puts the
asynchronous methods after the normal ones. These two additions are
simply semantic.

Tasks now have a method to cancel themselves using their task id. This
is provided as a convenience.

A new class called SimpleRunnable was added. It is an abstract Runnable
such that anonymous classes may subclass it. It provides six convenience
methods for scheduling as appropriate. It also provides a cancel method
for convenience. The functionality of SimpleRunnable only stores an
integer representing the task id. A SimpleRunnable can only be scheduled
once; attempting to reschedule results in IllegalStateException.
2012-10-14 02:05:29 -05:00
Wesley Wolfe
3313210590 Clarify some of the verbose in SimplePluginManager.
When an exception occurs, the version of the plugin is not included.
Having this information would be beneficial to plugin authors performing
debug.

The list of authors for NagAuthorException verbose (although unused)
would be more appropriate to simply include all authors, as opposed to
the first appearing.
2012-09-30 03:35:06 -05:00
Wesley Wolfe
c8dc8e682e Let version print partial matches for plugin name. Addresses BUKKIT-2383
If no plugin is found with the given name, the version command will
search all loaded plugins to find a case insensitive partial match for
the specified name and print to the sender all matches.
2012-09-28 16:50:32 -05:00
EvilSeph
ec823d16f4 Updated version to 1.3.2-R1.1-SNAPSHOT for development towards next release. 2012-09-28 16:33:59 -04:00
EvilSeph
5218c952a3 Updated version to 1.3.2-R1.0 in pom.xml for RB. 2012-09-28 16:25:34 -04:00
EvilSeph
2f8d9ffd55 Updated version to 1.3.2-R0.3-SNAPSHOT for development towards next release. 2012-09-26 19:20:08 -04:00
EvilSeph
f35e827917 Updated version to 1.3.2-R0.2 in pom.xml for Beta. 2012-09-26 19:16:09 -04:00
Wesley Wolfe
1bb902bc0a Remove internals from org.bukkit.Sound.
The internal Minecraft names of Sounds should not be exposed in the API.
2012-09-26 19:02:36 -04:00
mbax
a2566bfc3e Updated null checks in MetadataStoreBase. Fixes BUKKIT-1412
Previously, the method could be called with a null MetadataStore and stored.
In later execution null pointer exceptions would be generated when checking
for the plugin that the set Metadata belongs to.

Additionally, places where a plugin is referenced will now throw an
IllegalArgumentException if specified plugin is null. Using null would be an
obvious logical flaw, and in some cases produce additional exceptions later
in execution.
2012-08-26 22:09:21 -05:00
Wesley Wolfe
98d257daab Allow inherited methods to be event handlers. Addresses BUKKIT-2299
This change lets JavaPluginLoader use a temporary HashSet to store
methods that could possibly have the EventHandler annotation. Duplicates
are prevented by the nature of a Set.

Registering parent listeners is a breaking change for any listener
extending another listener and expecting parent listeners to not be
called. Changing this is justified by the ease-of-use and proper object
inheritance design. If this is undesired behavior, the method may be
overridden without reapplying the method with the EventHandler notation.
2012-08-26 21:14:28 -05:00
Wesley Wolfe
3ea3884cc5 Provide better verbose for registering listeners. Addresses BUKKIT-2391 2012-08-25 17:48:53 -05:00
EvilSeph
75749c6cc6 Updated version to 1.3.2-R0.2-SNAPSHOT for development towards next release. 2012-08-25 04:02:36 -04:00
EvilSeph
2b68ccd671 Updated version to 1.3.2-R0.1 in pom.xml for Beta. 2012-08-25 00:57:24 -04:00
EvilSeph
f99aee9b40 Updated version to 1.3.2-R0.1-SNAPSHOT for development towards next release. 2012-08-25 00:57:10 -04:00
feildmaster
a32b392c00 Add API for Sound, and playing the sounds for Worlds and Players. Adds BUKKIT-1430, BUKKIT-1226 and BUKKIT-2019 2012-08-21 17:15:48 -05:00
feildmaster
4d2dbee97f Add API to retrieve a players EnderChest. Adds BUKKIT-2016 2012-08-20 16:01:35 -05:00
EvilSeph
bb1f1904e9 Updated version to 1.3.1-R2.1-SNAPSHOT for development towards next release. 2012-08-19 09:01:06 -04:00
EvilSeph
5c33527403 Updated version to 1.3.1-R2.0 in pom.xml for RB. 2012-08-19 08:47:32 -04:00
Mike Primm
fb41daae01 Add isChunkInUse() to World. Addresses BUKKIT-2330 2012-08-19 07:56:39 -04:00
Wesley Wolfe
75e9cfb7a7 Fully restrict the org.bukkit and net.minecraft namespace 2012-08-19 07:42:20 -04:00
Wesley Wolfe
2265bb563b Let TripwireHook be attachable. Addresses BUKKIT-2278
This commit also makes TripwireHook consistent with other attachables
for the facing property.
2012-08-17 14:33:23 -05:00
feildmaster
28031fe19b Add interface for spawning FallingBlocks and correctly spawn a FallingBlock with the spawn(Location, FallingBlock.class) method. Adds BUKKIT-2282
Also add FallingBlock and methods.

Deprecated FallingSand to emphasize FallingBlock.
2012-08-14 07:39:44 -05:00
Wesley Wolfe
75d46314b6 Add API to set and get movement modifiers. Addresses BUKKIT-2205 2012-08-10 00:19:21 -05:00
Wesley Wolfe
7a6a3d9558 Change Player usage in unit tests to proxies 2012-08-10 00:03:21 -05:00
feildmaster
7ddfdb8253 Add API for getting and setting experience for BlockBreakEvent. Addresses BUKKIT-2033 2012-08-08 19:48:50 -05:00
feildmaster
7d9185e473 Add spaces to gamemode message. Fixes BUKKIT-2148 2012-08-08 19:48:49 -05:00
EvilSeph
fe0a09aebb Updated version to 1.3.1-R1.1-SNAPSHOT for development towards next release. 2012-08-07 17:10:02 -04:00
EvilSeph
233222bca5 Updated version to 1.3.1-R1.0 in pom.xml for RB 2012-08-07 03:10:25 -04:00
Wesley Wolfe
dafef287cb Purge outdated biomes. Fixes BUKKIT-1087 2012-08-07 01:55:48 -05:00
Wesley Wolfe
dc3fc6a702 Add Warning API and settings for Deprecated events 2012-08-07 00:16:57 -05:00
feildmaster
ebb4362cf6 Don't send duplicate messages for Gamemode and Time commands.
Gamemode gets sent with the packet.
2012-08-06 11:29:38 -05:00
feildmaster
09ef15e950 Update commands to match 1.3 vanilla commands 2012-08-06 06:59:46 -05:00
feildmaster
c809871558 Fail silently on incorrect number input 2012-08-06 06:59:45 -05:00
Wesley Wolfe
fee71b3ec9 Change inheritance for new MaterialData. 2012-08-05 22:01:54 -05:00
Mike Primm
67cf6c6bdf [Bleeding] Add new MaterialData classes for new blocks and update existing blocks with new data 2012-08-05 19:55:46 -05:00
Wesley Wolfe
e49a640760 BREAKING: replace defunct PlayerChatEvent with async chat. Addresses BUKKIT-2064
PlayerChatEvent is now Deprecated. It should be fired asynchronously, but
has not been so traditionally. To do so would massively break plugins that
rely on it.

AsyncPlayerChatEvent now replaces PlayerChatEvent. It uses comparable
functionality, but can be fired without synchronizing to the event manager.
The event will sometimes fire synchronously if triggered by a plugin.

Because PlayerChatEvent is now deprecated, PlayerCommandPreprocessEvent will
no longer extend PlayerChatEvent. This is almost completely source and
binary compatible, bar plugins that downcast to PlayerChatEvent.
Additionally, some methods that are non-functional have been marked
deprecated and indicate such.

Additionally, new constructors are now provided to allow for lazier
initialization of the receiving player set. A note has been added stating
plugins should be prepared for UnsupportedOperationExceptions if the caller
provides an unmodifiable collection.
2012-08-03 20:31:01 -05:00
Wesley Wolfe
0b2870a6fd Warn server owners of plugins using deprecated events. Fixes BUKKIT-2027 2012-08-02 23:21:02 -05:00
Travis Watkins
bc8f053e2a Test command permissions before running them. 2012-08-02 19:02:23 -05:00
feildmaster
c2e493480c Revive the toggledownfall permission! (and fix descriptions) 2012-08-02 18:31:19 -05:00
feildmaster
99f251cadb Add LargeBiomes WorldType. 2012-08-02 08:55:11 -05:00
feildmaster
110ad8c196 Update Bukkit for 1.3.1 changes 2012-08-02 04:54:21 -05:00
EvilSeph
6a53010c0c Updated version to 1.2.5-R5.1-SNAPSHOT for development towards next release. 2012-07-28 02:13:44 -04:00
EvilSeph
87b38c0578 Updated version to 1.2.5-R5.0 in pom.xml for RB. 2012-07-28 01:49:44 -04:00
feildmaster
ec51c24641 Add API to get a players experience to level (getExpToLevel). Implements BUKKIT-1906
This is the total experience one needs to gain a level.
2012-07-11 17:12:26 -05:00
feildmaster
c3830e0d22 Implement server.getMotd() for BUKKIT-1799 2012-07-04 23:21:03 -05:00
feildmaster
c65422de4b Don't "setLastDamageCause" in the DamageEvent constructor. Addresses BUKKIT-1881
This is now done after the event to allow you to be able to get previous damageCauses, and is now only applied if the event is not canceled.
2012-07-03 14:09:51 -05:00
TomyLobo
945ff9eebb Add an isValid() method to Entity. Addresses BUKKIT-810 2012-06-28 19:33:33 -05:00
Wesley Wolfe
2b3eaee7d9 Add check for existing config file. Addresses BUKKIT-1851 2012-06-28 16:39:19 -05:00
TomyLobo
6525a30e74 Add LivingEntity.hasLineOfSight. Addresses BUKKIT-1255 2012-06-23 10:58:01 -05:00
V10lator
e129c8363e Deprecate spawnCreature and add spawnEntity. Addresses BUKKIT-1168 2012-06-23 10:57:59 -05:00
Wesley Wolfe
c4fe5bfdf6 Add plugin channel events. Addresses BUKKIT-1844 2012-06-21 02:39:35 -05:00
Travis Ralston
ae3b5cc615 Add PlayerItemBreakEvent. Addresses BUKKIT-1600 2012-06-21 02:08:31 -05:00
Wesley Wolfe
ae4f1c05d8 Revert "Shift plugin initialization; Addresses BUKKIT-1788"
This reverts commit 27cb5e7c9c. Issues
were discovered with shared class loaders.
2012-06-16 00:48:47 -05:00
Wesley Wolfe
27cb5e7c9c Shift plugin initialization; Addresses BUKKIT-1788 2012-06-15 23:48:09 -05:00
obnoxint
218fa3197f Add NotePlayEvent. Fixes BUKKIT-1779 2012-06-14 20:58:19 -05:00
Wesley Wolfe
63669e8d3d Add asynchronous pre-login event; Addresses BUKKIT-1213 2012-06-13 23:01:03 -05:00
Wesley Wolfe
4ebefa5b3a Support asynchronous events; Addresses BUKKIT-1212 2012-06-13 23:01:03 -05:00
H31IX
40ca05a5c7 Add PlayerToggleFlightEvent. Fixes BUKKIT-1696 2012-06-13 22:19:51 -05:00
EvilSeph
e6abf99fb0 Updated version to 1.2.5-R4.1-SNAPSHOT for development towards next release. 2012-06-09 21:40:24 -04:00
EvilSeph
e236d995b6 Updated version to 1.2.5-R4.0 in pom.xml for RB. 2012-06-09 21:04:31 -04:00
Wesley Wolfe
6d09f52afd Check for non-existent class alias; Fixes BUKKIT-1780 2012-06-09 15:58:53 -05:00
feildmaster
537138e9b2 Javadoc updates
Fixes BUKKIT-1653, Fixes BUKKIT-1383 and Fixes BUKKIT-1644
2012-06-03 05:40:54 -05:00
Wesley Wolfe
fbdceefaa7 Change logger references to explicitly use plugin logger 2012-05-26 14:33:27 -05:00
Wesley Wolfe
6807c05321 Reverse disable order; Addresses BUKKIT-1389 2012-05-26 01:28:51 -05:00
EvilSeph
92664af58e Updated version to 1.2.5-R3.1-SNAPSHOT for development towards next release. 2012-05-26 02:23:55 -04:00
EvilSeph
ed71c68a59 Updated version to 1.2.5-R3.0 in pom.xml for RB. 2012-05-26 00:25:51 -04:00
Wesley Wolfe
30545e1a50 Make class loader preference predictable; Fixes BUKKIT-1591 2012-05-25 15:47:39 -05:00
Acrobot
5ae3c99bf5 Use existing function to get opposite block face 2012-05-25 05:01:47 -05:00
Wesley Wolfe
5630ae217c Add getName() to AnimalTamer 2012-05-24 22:33:45 -05:00
feildmaster
a720c8e7fa Updated version to 1.2.5-R2.1-SNAPSHOT for development towards next release 2012-05-19 17:54:30 -05:00
EvilSeph
a092009d5c Updated version to 1.2.5-R2.0 in pom.xml for RB. 2012-05-17 23:19:56 -04:00
Travis Watkins
7bbda1b7ab Optimize ChatColor.getLastColors.
ChatColor searches from the start to the end of a string for chat format
characters but this always has to search the entire string. By starting
from the end of the string and working backwards we can stop searching once
we find a color code or a reset code as any previous formatting is wiped
out by these.
2012-05-16 18:42:39 -05:00
595 changed files with 25925 additions and 5287 deletions

4
.gitignore vendored
View File

@@ -22,10 +22,10 @@
/manifest.mf
# Mac filesystem dust
/.DS_Store
.DS_Store
# intellij
*.iml
*.ipr
*.iws
.idea/
.idea/

497
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,497 @@
# How to Contribute
The Bukkit project prides itself on being community built and driven. We love it when members of our community want to jump right in and get involved, so here's what you need to know.
## Quick Guide
1. Create or find an issue to address on our [JIRA issue tracker](http://leaky.bukkit.org).
- Does your proposed change [fit Bukkit's goals](#does-the-change-fit-bukkits-goals)?
- Fork the repository if you haven't done so already.
- Make your changes in a new branch (if your change affects both Bukkit and CraftBukkit, we highly suggest you use the same name for your branches in both repos).
- Test your changes.
- Push to your fork and submit a pull request.
- **Note:** The project is put under a code freeze leading up to the release of a Minecraft update in order to give the Bukkit team a static code base to work on.
![Life Cycle of a Bukkit Improvement](http://i.imgur.com/Ed6T7AE.png)
## Getting Started
- You'll need a free [JIRA account](http://leaky.bukkit.org) (on our issue tracker affectionately called Leaky).
- You'll need a free [GitHub account](https://github.com/signup/free).
- Make sure you have a JIRA ticket for your issue at hand.
* Either search the list of current issues and find an appropriate issue.
* Or create one yourself if one does not already exist.
* When creating an issue, make sure to clearly describe the issue (including steps to reproduce it if it is a bug).
- Fork the repository on GitHub.
- **Note:** The project is put under a code freeze leading up to the release of a Minecraft update in order to give the Bukkit team a static code base to work on.
## Does the Change Fit Bukkit's Goals?
As a rough guideline, ask yourself the following questions to determine if your proposed change fits the Bukkit project's goals. Please remember that this is only a rough guideline and may or may not reflect the definitive answer to this question.
* Does it expose an implementation detail of the server software, the protocol or file formats?
If your change revolves around an implementation detail then it is not proper API design. Examples of bad API design would be along the lines of a packet API, an NBT storage API, or basing an enum on implementation values.
* Does it result in unexpected behaviour as defined by the Vanilla specification?
One of the goals of the Bukkit project is to be an extended Minecraft vanilla server - meaning: if you choose to run the Bukkit server without any plugins, it should function exactly as the Minecraft server would with some rare exceptions. If your change alters the behaviour of the server in such a way that you would not have the same experience as you would in Vanilla, your change does not fit the Bukkit project's goals.
* Does it expose an issue or vulnerability when operating within the Vanilla environment?
One of the goals of the Bukkit project is to be able to operate within the limitations of the Vanilla environment. If your change results in or exposes the ability to, for example, crash the client when invalid data is set, it does not fit the Bukkit project's needs.
If you answered yes to any of these questions, chances are high your change does not fit the Bukkit project's goals and will most likely not be accepted. Regardless, there are a few other important questions you need to ask yourself before you start working on a change:
* Is this change reasonably supportable and maintainable?
* Is this change future proof?
## Making the Changes
* Create a branch on your fork where you'll be making your changes.
* Name your branch something relevant to the change you are looking to make.
* Note: if your changes affect both Bukkit and CraftBukkit, it is highly suggested you use the same branch name on both repos.
* To create a branch in Git;
* `git branch relevantBranchName`
* Then checkout the new branch with `git checkout relevantBranchName`
* Check for unnecessary whitespace with `git diff --check` before committing.
* Make sure your code meets [our requirements](#code-requirements).
* If the work you want to do involves editing Minecraft classes, be sure to read over the [Using Minecraft Internals](#using-minecraft-internals) section.
* Make sure your commit messages are in the [proper format](#commit-message-example).
* Test your changes to make sure it actually addresses the issue it should.
* Make sure your code compiles under Java 6, as that is what the project has to be built with.
### Code Requirements
* We generally follow the [Sun/Oracle coding standards](http://www.oracle.com/technetwork/java/javase/documentation/codeconvtoc-136057.html).
* No tabs; use 4 spaces instead.
* No trailing whitespaces.
* No CRLF line endings, LF only, set your Gits 'core.autocrlf' to 'true'.
These whitespace requirements are easily and often overlooked. They are critical formatting requirements designed to help simplify a shared heterogeneous development environment. Learn how your IDE functions in order to show you these characters and verify them. Analyse the git diff closely to verify every character and if the PR should include the character change. It is tedious and it is critical.
Eclipse: http://stackoverflow.com/a/11596227/532590
NetBeans: http://stackoverflow.com/a/1866385/532590
* No 80 column limit or 'weird' midstatement newlines.
* Any major additions should have documentation ready and provided if applicable (this is usually the case).
* Try to follow test driven development where applicable.
Bukkit employs JUnit (http://www.vogella.com/articles/JUnit/article.html) for testing and PRs should attempt to integrate with that framework as appropriate. Bukkit is a large project and what seems simple to a PR author at the time of writing a PR may easily be overlooked later by other authors and updates. Including unit tests with your PR will help to ensure the PR can be easily maintained over time and encourage the Bukkit Team to pull the PR.
* There needs to be a new line at the end of every file.
* Imports should be organised by alphabetical order, separated and grouped by package.
**For example:**
```java
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import java.util.concurrent.Callable;
// CraftBukkit start
import java.io.UnsupportedEncodingException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.logging.Level;
import java.util.HashSet;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.util.LazyPlayerSet;
import org.bukkit.craftbukkit.util.Waitable;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerAnimationEvent;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.bukkit.event.player.PlayerToggleSprintEvent;
import org.bukkit.event.inventory.*;
import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.event.player.PlayerPortalEvent;
import org.bukkit.event.player.PlayerToggleFlightEvent;
import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.InventoryView;
// CraftBukkit end
```
### Using Minecraft Internals
#### Importing a New Minecraft Class
When contributing to the Bukkit project, you will likely find that you need to edit a Minecraft class that isn't already found within the project. In this case, you need to look at [our mc-dev repository](https://github.com/Bukkit/mc-dev), find the class you need, add it to the CraftBukkit repo and include it in its own special commit separate from your other changes. The commit message of this special commit should simply be "Add x for diff visibility", where x is the name of the file you are adding from mc-dev.
If, however, you need to import multiple files from mc-dev into the Bukkit project, they should all be contained in the same special commit with the commit message "Add files for diff visibility". Note how the commit message no longer specifically mentions any class names.
#### Making Changes to Minecraft Classes
The Bukkit project employs a Minimal Diff policy to help guide when changes should be made to Minecraft classes and what those changes should be. This is to ensure that any changes made have the smallest impact possible on the update process we go through whenever a Minecraft update is released. As well as keeping the Minimal Diff policy in mind, every change made to a Minecraft class needs to be marked as such with the appropriate CraftBukkit comment.
##### Minimal Diff Policy
The Minimal Diff policy is a really important part of the project as it reminds us that every change to the Minecraft Internals has an impact on our update process. When people think of the phrase "minimal diffs", they often take it to the extreme - they go completely out of their way to abstract the changes they are trying to make away from editing Minecraft's classes as much as possible. However, this isn't what we mean by "minimal diffs". Instead, when trying to understand the minimal diffs policy, it helps to keep in mind its end goal: to reduce the impact changes we make to Minecraft's internals have on our update process.
Put simply, the Minimal Diffs Policy simply means to make the smallest change in a Minecraft class possible without duplicating logic.
Here are a few tips you should keep in mind or common areas you should focus on:
* Try to avoid duplicating logic or code when making changes.
* Try to keep your changes easily discernible - don't nest or group several unrelated changes together.
* If you only use an import once within a class, don't import it and use fully qualified names instead.
* Try to employ "short circuiting" of logic if at all possible. This means that you should force a conditional to be the value needed to side-step the code block if you would like to ignore that block of code.
**For example, to short circuit this:**
```java
if (!this.world.isStatic && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) {
this.die();
this.h();
}
```
**You would do this:**
```java
if (false && !this.world.isStatic && !this.dead && d0 * d0 + d1 * d1 + d2 * d2 > 0.0D) { // CraftBukkit - not needed
this.die();
this.h();
}
```
* When adding a validation check, see if the Validate package we already use has a better, more concise method you can use instead.
**For example, you should use:**
```java
Validate.notNull(sender, "Sender cannot be null");
```
**Instead of:**
```java
if (sender == null) {
throw new IllegalArgumentException("Sender cannot be null");
}
```
* When the change you are attempting to make involves removing code, instead of removing it outright, you should comment it out.
**For example:**
```java
// CraftBukkit start - special case dropping so we can get info from the tile entity
public void dropNaturally(World world, int i, int j, int k, int l, float f, int i1) {
if (world.random.nextFloat() < f) {
ItemStack itemstack = new ItemStack(Item.SKULL.id, 1, this.getDropData(world, i, j, k));
TileEntitySkull tileentityskull = (TileEntitySkull) world.getTileEntity(i, j, k);
if (tileentityskull.getSkullType() == 3 && tileentityskull.getExtraType() != null && tileentityskull.getExtraType().length() > 0) {
itemstack.setTag(new NBTTagCompound());
itemstack.getTag().setString("SkullOwner", tileentityskull.getExtraType());
}
this.b(world, i, j, k, itemstack);
}
}
// CraftBukkit end
public void a(World world, int i, int j, int k, int l, EntityHuman entityhuman) {
if (entityhuman.abilities.canInstantlyBuild) {
l |= 8;
world.setData(i, j, k, l, 4);
}
super.a(world, i, j, k, l, entityhuman);
}
public void remove(World world, int i, int j, int k, int l, int i1) {
if (!world.isStatic) {
/* CraftBukkit start - drop item in code above, not here
if ((i1 & 8) == 0) {
ItemStack itemstack = new ItemStack(Item.SKULL.id, 1, this.getDropData(world, i, j, k));
TileEntitySkull tileentityskull = (TileEntitySkull) world.getTileEntity(i, j, k);
if (tileentityskull.getSkullType() == 3 && tileentityskull.getExtraType() != null && tileentityskull.getExtraType().length() > 0) {
itemstack.setTag(new NBTTagCompound());
itemstack.getTag().setString("SkullOwner", tileentityskull.getExtraType());
}
this.b(world, i, j, k, itemstack);
}
// CraftBukkit end */
super.remove(world, i, j, k, l, i1);
}
}
```
##### General Guidelines
When editing Minecraft's classes, we have a set of rules and guidelines that need to be followed to keep us sane when it comes time for us to update Bukkit.
**CraftBukkit comments**
Changes to a Minecraft class should be clearly marked using CraftBukkit comments. Here are a few tips to help explain what kind of CraftBukkit comment to use and where to use them:
* Regardless of what kind of CraftBukkit comment you use, please take care to be explicit and exact with your usage. If the "C" in "CraftBukkit" is capitalised in the example, you should capitalise it when you use it. If the "start" begins with a lowercase "s", you should make sure yours does too.
* If the change only affects one line of code, you should use an end of line CraftBukkit comment.
**Examples:**
If the change is obvious when looking at the diff, then you just need a simple end of line CraftBukkit comment.
```java
if (true || minecraftserver.getAllowNether()) { // CraftBukkit
```
If, however, the change is something important to note or difficult to discern, you should include a reason at the end of the end of line CraftBukkit comment.
```java
public int fireTicks; // CraftBukkit - private -> public
```
If adding the CraftBukkit comment to the end of the line negatively affects the readability of the code, then you should place the CraftBukkit comment on a new line above the change you made.
```java
// CraftBukkit
if (!isEffect && !world.isStatic && world.difficulty >= 2 && world.areChunksLoaded(MathHelper.floor(d0), MathHelper.floor(d1), MathHelper.floor(d2), 10)) {
```
* If the change affects more than one line, you should use a multi-line CraftBukkit comment.
**Examples:**
The majority of the time multi-line changes should be accompanied by a reason since they're usually much more complicated than a single line change. We'd like to suggest you follow the same rule as above: if the change is something important to note or difficult to discern, you should include a reason at the end of the end of line CraftBukkit comment, however it is not always clear if this is the case. Looking through the code in the project, you'll see that we sometimes include a reason when we should have left it off and vice versa.
```java
// CraftBukkit start - special case dropping so we can get info from the tile entity
public void dropNaturally(World world, int i, int j, int k, int l, float f, int i1) {
if (world.random.nextFloat() < f) {
ItemStack itemstack = new ItemStack(Item.SKULL.id, 1, this.getDropData(world, i, j, k));
TileEntitySkull tileentityskull = (TileEntitySkull) world.getTileEntity(i, j, k);
if (tileentityskull.getSkullType() == 3 && tileentityskull.getExtraType() != null && tileentityskull.getExtraType().length() > 0) {
itemstack.setTag(new NBTTagCompound());
itemstack.getTag().setString("SkullOwner", tileentityskull.getExtraType());
}
this.b(world, i, j, k, itemstack);
}
}
// CraftBukkit end
````
Otherwise, just use a multi-line CraftBukkit comment without a reason.
```java
// CraftBukkit start
BlockIgniteEvent event = new BlockIgniteEvent(this.cworld.getBlockAt(i, j, k), BlockIgniteEvent.IgniteCause.LIGHTNING, null);
world.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
world.setTypeIdUpdate(i, j, k, Block.FIRE.id);
}
// CraftBukkit end
```
* CraftBukkit comments should be on the same indentation level of the code block it is in.
**For example:**
```java
if (j == 1) {
// CraftBukkit start - store a reference
ItemStack itemstack4 = playerinventory.getCarried();
if (itemstack4.count > 0) {
entityhuman.drop(itemstack4.a(1));
}
if (itemstack4.count == 0) {
// CraftBukkit end
playerinventory.setCarried((ItemStack) null);
}
}
```
**Other guidelines**
* When adding imports to a Minecraft class, they should be organised by alphabetical order, separated and grouped by package.
**For example:**
```java
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Random;
import java.util.concurrent.Callable;
// CraftBukkit start
import java.io.UnsupportedEncodingException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.logging.Level;
import java.util.HashSet;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.CraftWorld;
import org.bukkit.craftbukkit.inventory.CraftInventoryView;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.craftbukkit.util.LazyPlayerSet;
import org.bukkit.craftbukkit.util.Waitable;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.craftbukkit.event.CraftEventFactory;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerAnimationEvent;
import org.bukkit.event.player.PlayerChatEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerItemHeldEvent;
import org.bukkit.event.player.PlayerKickEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.event.player.PlayerToggleSneakEvent;
import org.bukkit.event.player.PlayerToggleSprintEvent;
import org.bukkit.event.inventory.*;
import org.bukkit.event.inventory.InventoryType.SlotType;
import org.bukkit.event.player.PlayerPortalEvent;
import org.bukkit.event.player.PlayerToggleFlightEvent;
import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.InventoryView;
// CraftBukkit end
```
* Do not remove unused imports if they are not marked by CraftBukkit comments.
### Commit Message Example
> Provide an example commit for CONTRIBUTING.md. Fixes BUKKIT-1
>
> The CONTRIBUTING.md is missing an example commit message. Without this
> commit, we are unable to provide potential contributors with a helpful example,
> forcing developers to guess at what an acceptable commit message would look
> like. This commit fixes this issue by providing a clear and informative example
> for contributors to base their work off of.
### Commit Message Expectations
The first line in a commit message is an imperative statement briefly explaining what the commit is achieving with an associated ticket number from our JIRA, in the form of BUKKIT-#. See the list of acceptable keywords to reference tickets with for more information on this.
The body of the commit message needs to describe how the code behaves without this change, why this is a problem and how this commit addresses it. The body of the commit message should be restricted by a 78 character, plus newline, limit per line (meaning: once you hit about 78 characters, you should explicitly start a new line in the commit message).
Acceptable keywords to reference tickets with:
* **Fixes** BUKKIT-1 - this commit fixes the bug detailed in BUKKIT-1
* **Adds** BUKKIT-2 - this commit adds the new feature requested by BUKKIT-2
You can reference multiple tickets in a single commit message, for example: "Fixes BUKKIT-1, BUKKIT-2" or "Adds BUKKIT-1, BUKKIT-2" without closing punctuation.
## Submitting the Changes
* Push your changes to a topic branch in your fork of the repository.
* Submit a pull request to the relevant repository in the Bukkit organization.
* Make sure your pull request meets [our expectations](#pull-request-formatting-expectations) before submitting.
* No merges should be included in any pull requests.
* Update your JIRA ticket to reflect that you have submitted a pull request and are ready for it to be reviewed.
* Include a link to the pull request in the ticket.
* Follow our [Tips to Get Your Pull Request Accepted](#tips-to-get-your-pull-request-accepted).
* **Note:** The project is put under a code freeze leading up to the release of a Minecraft update in order to give the Bukkit team a static code base to work on.
### Pull Request Formatting Expectations
#### Title
> [PR Type] Brief summary. Fixes BUKKIT-####
> PR Type can be B for Bukkit, C for CraftBukkit, B+C for a PR in both sides
>
> Title Example:
> [B+C] Provide an example commit for CONTRIBUTING.md. Fixes BUKKIT-1
#### Description:
> ##### The Issue:
> Paragraphs explaining what the issue the PR is meant to be addressing.
>
> ##### Justification for this PR:
> Paragraphs providing justification for the PR
>
> ##### PR Breakdown:
> Paragraphs breaking down what the PR is doing, in detail.
>
> ##### Testing Results and Materials:
> Paragraphs describing what you did to test the code in this PR and links to pre-compiled test binaries and source.
>
> ##### Relevant PR(s):
> This should be links to accompanying PRs, or alternate PRs that attempted to perform the task. Each reference should have a reason attached as to why it is being referenced (for example: "Similar to PR ### but won't empty your Bukkits"). Accompanying PRs need no explanation, but still need to be linked.
>
> B-#### - https://github.com/Bukkit/Bukkit/pull/#### - Reason
> CB-#### - https://github.com/Bukkit/CraftBukkit/pull/#### - Reason
>
> ##### JIRA Ticket:
> BUKKIT-#### - https://bukkit.atlassian.net/browse/BUKKIT-####
>
> ##### Pull Request Check List (For Your Use):
>
>**General:**
>
>- [ ] Fits Bukkit's Goals
>- [ ] Leaky Ticket Ready
>- [ ] Code Meets Requirements
>- [ ] Code is Documented
>- [ ] Code Addresses Leaky Ticket
>- [ ] Followed Pull Request Format
>- [ ] Tested Code
>- [ ] Included Test Material and Source
>
>**If Applicable:**
>
>- [ ] Importing New Minecraft Classes In Special Commit
>- [ ] Follows Minimal Diff Policy
>- [ ] Uses Proper CraftBukkit Comments
>- [ ] Imports Are Ordered, Separated and Organised Properly
### Tips to Get Your Pull Request Accepted
Making sure you follow the above conventions is important, but just the beginning. Follow these tips to better the chances of your pull request being accepted and pulled.
* Your change should [fit with Bukkit's goals](#does-the-change-fit-bukkits-goals).
* Make sure you follow all of our conventions to the letter.
* Make sure your code compiles under Java 6.
* Check for misplaced whitespaces. It may be invisible, but [we notice](https://github.com/Bukkit/CraftBukkit/pull/1070).
* Provide proper JavaDocs where appropriate.
* JavaDocs should detail every limitation, caveat and gotcha the code has.
* Provide proper accompanying documentation where appropriate.
* Test your code and provide testing material.
* For example: adding an event? Test it with a test plugin and provide us with that plugin and its source.
* Make sure to follow coding best practises.
* Your pull request should adhere to our [Pull Request Formatting Expectations](#pull-request-formatting-expectations).
* **Note:** The project is put under a code freeze leading up to the release of a Minecraft update in order to give the Bukkit team a static code base to work on.
## Useful Resources
* [An example pull request demonstrating the things we look out for](https://github.com/Bukkit/CraftBukkit/pull/1070)
* [Handy gist version of our Pull Request Format Template](https://gist.github.com/EvilSeph/35bb477eaa1dffc5f1d7)
* [More information on contributing](http://wiki.bukkit.org/Getting_Involved)
* [Leaky, Our Issue Tracker (JIRA)](http://leaky.bukkit.org)
* [General GitHub documentation](http://help.github.com/)
* [GitHub pull request documentation](http://help.github.com/send-pull-requests/)
* [Join us on IRC - #bukkitdev @ irc.esper.net](http://wiki.bukkit.org/IRC)

View File

@@ -4,7 +4,8 @@ Bukkit
A Minecraft Server API.
Website: [http://bukkit.org](http://bukkit.org)
Bugs/Suggestions: [http://leaky.bukkit.org](http://leaky.bukkit.org)
Bugs/Suggestions: [http://leaky.bukkit.org](http://leaky.bukkit.org)
Contributing Guidelines: [CONTRIBUTING.md](https://github.com/Bukkit/Bukkit/blob/master/CONTRIBUTING.md)
Compilation
-----------
@@ -13,32 +14,3 @@ We use maven to handle our dependencies.
* Install [Maven 3](http://maven.apache.org/download.html)
* Check out this repo and: `mvn clean install`
Coding and Pull Request Conventions
-----------
* We generally follow the Sun/Oracle coding standards.
* No tabs; use 4 spaces instead.
* No trailing whitespaces.
* No CRLF line endings, LF only, put your gits 'core.autocrlf' on 'true'.
* No 80 column limit or 'weird' midstatement newlines.
* The number of commits in a pull request should be kept to a minimum (squish them into one most of the time - use common sense!).
* No merges should be included in pull requests unless the pull request's purpose is a merge.
* Pull requests should be tested (does it compile? AND does it work?) before submission.
* Any major additions should have documentation ready and provided if applicable (this is usually the case).
* Most pull requests should be accompanied by a corresponding Leaky ticket so we can associate commits with Leaky issues (this is primarily for changelog generation on dl.bukkit.org).
* Try to follow test driven development where applicable.
Tips to get your pull request accepted
-----------
Making sure you follow the above conventions is important, but just the beginning. Follow these tips to better the chances of your pull request being accepted and pulled.
* Make sure you follow all of our conventions to the letter.
* Make sure your code compiles under Java 5.
* Provide proper JavaDocs where appropriate.
* Provide proper accompanying documentation where appropriate.
* Test your code.
* Make sure to follow coding best practises.
* Provide a test plugin binary and source for us to test your code with.
* Your pull request should link to accompanying pull requests.
* The description of your pull request should provide detailed information on the pull along with justification of the changes where applicable.

20
pom.xml
View File

@@ -2,7 +2,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>org.bukkit</groupId>
<artifactId>bukkit</artifactId>
<version>1.2.5-R1.4-SNAPSHOT</version>
<version>1.7.10-R0.1-SNAPSHOT</version>
<name>Bukkit</name>
<url>http://www.bukkit.org</url>
@@ -43,10 +43,10 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<version>2.3.2</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
@@ -131,20 +131,14 @@
<!-- testing -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit-dep</artifactId>
<version>4.10</version>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
<exclusions>
<exclusion>
<artifactId>hamcrest-core</artifactId>
<groupId>org.hamcrest</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-library</artifactId>
<version>1.2.1</version>
<version>1.3</version>
<scope>test</scope>
</dependency>
</dependencies>

View File

@@ -1,78 +1,69 @@
package org.bukkit;
import java.util.Map;
import com.google.common.collect.Maps;
/**
* Represents an achievement, which may be given to players
* Represents an achievement, which may be given to players.
*/
public enum Achievement {
OPEN_INVENTORY(0),
MINE_WOOD(1),
BUILD_WORKBENCH(2),
BUILD_PICKAXE(3),
BUILD_FURNACE(4),
ACQUIRE_IRON(5),
BUILD_HOE(6),
MAKE_BREAD(7),
BAKE_CAKE(8),
BUILD_BETTER_PICKAXE(9),
COOK_FISH(10),
ON_A_RAIL(11),
BUILD_SWORD(12),
KILL_ENEMY(13),
KILL_COW(14),
FLY_PIG(15),
SNIPE_SKELETON(16),
GET_DIAMONDS(17),
NETHER_PORTAL(18),
GHAST_RETURN(19),
GET_BLAZE_ROD(20),
BREW_POTION(21),
END_PORTAL(22),
THE_END(23),
ENCHANTMENTS(24),
OVERKILL(25),
BOOKCASE(26);
OPEN_INVENTORY,
MINE_WOOD (OPEN_INVENTORY),
BUILD_WORKBENCH (MINE_WOOD),
BUILD_PICKAXE (BUILD_WORKBENCH),
BUILD_FURNACE (BUILD_PICKAXE),
ACQUIRE_IRON (BUILD_FURNACE),
BUILD_HOE (BUILD_WORKBENCH),
MAKE_BREAD (BUILD_HOE),
BAKE_CAKE (BUILD_HOE),
BUILD_BETTER_PICKAXE (BUILD_PICKAXE),
COOK_FISH (BUILD_FURNACE),
ON_A_RAIL (ACQUIRE_IRON),
BUILD_SWORD (BUILD_WORKBENCH),
KILL_ENEMY (BUILD_SWORD),
KILL_COW (BUILD_SWORD),
FLY_PIG (KILL_COW),
SNIPE_SKELETON (KILL_ENEMY),
GET_DIAMONDS (ACQUIRE_IRON),
NETHER_PORTAL (GET_DIAMONDS),
GHAST_RETURN (NETHER_PORTAL),
GET_BLAZE_ROD (NETHER_PORTAL),
BREW_POTION (GET_BLAZE_ROD),
END_PORTAL (GET_BLAZE_ROD),
THE_END (END_PORTAL),
ENCHANTMENTS (GET_DIAMONDS),
OVERKILL (ENCHANTMENTS),
BOOKCASE (ENCHANTMENTS),
EXPLORE_ALL_BIOMES (END_PORTAL),
SPAWN_WITHER (THE_END),
KILL_WITHER (SPAWN_WITHER),
FULL_BEACON (KILL_WITHER),
BREED_COW (KILL_COW),
DIAMONDS_TO_YOU (GET_DIAMONDS),
;
/**
* The offset used to distinguish Achievements and Statistics
*/
public final static int STATISTIC_OFFSET = 0x500000;
private final static Map<Integer, Achievement> BY_ID = Maps.newHashMap();
private final int id;
private final Achievement parent;
private Achievement(int id) {
this.id = STATISTIC_OFFSET + id;
private Achievement() {
parent = null;
}
private Achievement(Achievement parent) {
this.parent = parent;
}
/**
* Gets the ID for this achievement.
* <p />
* Note that this is offset using {@link #STATISTIC_OFFSET}
*
* @return ID of this achievement
* Returns whether or not this achievement has a parent achievement.
*
* @return whether the achievement has a parent achievement
*/
public int getId() {
return id;
public boolean hasParent() {
return parent != null;
}
/**
* Gets the achievement associated with the given ID.
* <p />
* Note that the ID must already be offset using {@link #STATISTIC_OFFSET}
*
* @param id ID of the achievement to return
* @return Achievement with the given ID
* Returns the parent achievement of this achievement, or null if none.
*
* @return the parent achievement or null
*/
public static Achievement getById(int id) {
return BY_ID.get(id);
}
static {
for (Achievement achievement : values()) {
BY_ID.put(achievement.id, achievement);
}
public Achievement getParent() {
return parent;
}
}

View File

@@ -29,12 +29,13 @@ public enum Art {
STAGE(16, 2, 2),
VOID(17, 2, 2),
SKULL_AND_ROSES(18, 2, 2),
FIGHTERS(19, 4, 2),
POINTER(20, 4, 4),
PIGSCENE(21, 4, 4),
BURNINGSKULL(22, 4, 4),
SKELETON(23, 4, 3),
DONKEYKONG(24, 4, 3);
WITHER(19, 2, 2),
FIGHTERS(20, 4, 2),
POINTER(21, 4, 4),
PIGSCENE(22, 4, 4),
BURNINGSKULL(23, 4, 4),
SKELETON(24, 4, 3),
DONKEYKONG(25, 4, 3);
private int id, width, height;
private static final HashMap<String, Art> BY_NAME = Maps.newHashMap();
@@ -68,7 +69,9 @@ public enum Art {
* Get the ID of this painting.
*
* @return The ID of this painting
* @deprecated Magic value
*/
@Deprecated
public int getId() {
return id;
}
@@ -78,14 +81,16 @@ public enum Art {
*
* @param id The ID
* @return The painting
* @deprecated Magic value
*/
@Deprecated
public static Art getById(int id) {
return BY_ID.get(id);
}
/**
* Get a painting by its unique name
* <p />
* <p>
* This ignores underscores and capitalization
*
* @param name The name

View File

@@ -0,0 +1,127 @@
package org.bukkit;
import java.util.Date;
/**
* A single entry from a ban list. This may represent either a player ban or
* an IP ban.
* <p>
* Ban entries include the following properties:
* <table border=1>
* <tr>
* <th>Property</th>
* <th>Description</th>
* </tr><tr>
* <td>Target Name / IP Address</td>
* <td>The target name or IP address</td>
* </tr><tr>
* <td>Creation Date</td>
* <td>The creation date of the ban</td>
* </tr><tr>
* <td>Source</td>
* <td>The source of the ban, such as a player, console, plugin, etc</td>
* </tr><tr>
* <td>Expiration Date</td>
* <td>The expiration date of the ban</td>
* </tr><tr>
* <td>Reason</td>
* <td>The reason for the ban</td>
* </tr>
* </table>
* <p>
* Unsaved information is not automatically written to the implementation's
* ban list, instead, the {@link #save()} method must be called to write the
* changes to the ban list. If this ban entry has expired (such as from an
* unban) and is no longer found in the list, the {@link #save()} call will
* re-add it to the list, therefore banning the victim specified.
* <p>
* Likewise, changes to the associated {@link BanList} or other entries may or
* may not be reflected in this entry.
*/
public interface BanEntry {
/**
* Gets the target involved. This may be in the form of an IP or a player
* name.
*
* @return the target name or IP address
*/
public String getTarget();
/**
* Gets the date this ban entry was created.
*
* @return the creation date
*/
public Date getCreated();
/**
* Sets the date this ban entry was created.
*
* @param created the new created date, cannot be null
* @see #save() saving changes
*/
public void setCreated(Date created);
/**
* Gets the source of this ban.
* <p>
* Note: A source is considered any String, although this is generally a
* player name.
*
* @return the source of the ban
*/
public String getSource();
/**
* Sets the source of this ban.
* <p>
* Note: A source is considered any String, although this is generally a
* player name.
*
* @param source the new source where null values become empty strings
* @see #save() saving changes
*/
public void setSource(String source);
/**
* Gets the date this ban expires on, or null for no defined end date.
*
* @return the expiration date
*/
public Date getExpiration();
/**
* Sets the date this ban expires on. Null values are considered
* "infinite" bans.
*
* @param expiration the new expiration date, or null to indicate an
* eternity
* @see #save() saving changes
*/
public void setExpiration(Date expiration);
/**
* Gets the reason for this ban.
*
* @return the ban reason, or null if not set
*/
public String getReason();
/**
* Sets the reason for this ban. Reasons must not be null.
*
* @param reason the new reason, null values assume the implementation
* default
* @see #save() saving changes
*/
public void setReason(String reason);
/**
* Saves the ban entry, overwriting any previous data in the ban list.
* <p>
* Saving the ban entry of an unbanned player will cause the player to be
* banned once again.
*/
public void save();
}

View File

@@ -0,0 +1,72 @@
package org.bukkit;
import java.util.Date;
import java.util.Set;
/**
* A ban list, containing bans of some {@link Type}.
*/
public interface BanList {
/**
* Represents a ban-type that a {@link BanList} may track.
*/
public enum Type {
/**
* Banned player names
*/
NAME,
/**
* Banned player IP addresses
*/
IP,
;
}
/**
* Gets a {@link BanEntry} by target.
*
* @param target entry parameter to search for
* @return the corresponding entry, or null if none found
*/
public BanEntry getBanEntry(String target);
/**
* Adds a ban to the this list. If a previous ban exists, this will
* update the previous entry.
*
* @param target the target of the ban
* @param reason reason for the ban, null indicates implementation default
* @param expires date for the ban's expiration (unban), or null to imply
* forever
* @param source source of the ban, null indicates implementation default
* @return the entry for the newly created ban, or the entry for the
* (updated) previous ban
*/
public BanEntry addBan(String target, String reason, Date expires, String source);
/**
* Gets a set containing every {@link BanEntry} in this list.
*
* @return an immutable set containing every entry tracked by this list
*/
public Set<BanEntry> getBanEntries();
/**
* Gets if a {@link BanEntry} exists for the target, indicating an active
* ban status.
*
* @param target the target to find
* @return true if a {@link BanEntry} exists for the name, indicating an
* active ban status, false otherwise
*/
public boolean isBanned(String target);
/**
* Removes the specified target from this list, therefore indicating a
* "not banned" status.
*
* @param target the target to remove from this list
*/
public void pardon(String target);
}

View File

@@ -8,20 +8,28 @@ package org.bukkit;
public interface BlockChangeDelegate {
/**
* Set a block type at the specified coordinates without doing all world updates and notifications.
* It is safe to have this call World.setTypeId, but it may be slower than World.setRawTypeId.
* Set a block type at the specified coordinates without doing all world
* updates and notifications.
* <p>
* It is safe to have this call World.setTypeId, but it may be slower than
* World.setRawTypeId.
*
* @param x X coordinate
* @param y Y coordinate
* @param z Z coordinate
* @param typeId New block ID
* @return true if the block was set successfully
* @deprecated Magic value
*/
@Deprecated
public boolean setRawTypeId(int x, int y, int z, int typeId);
/**
* Set a block type and data at the specified coordinates without doing all world updates and notifications.
* It is safe to have this call World.setTypeId, but it may be slower than World.setRawTypeId.
* Set a block type and data at the specified coordinates without doing
* all world updates and notifications.
* <p>
* It is safe to have this call World.setTypeId, but it may be slower than
* World.setRawTypeId.
*
* @param x X coordinate
* @param y Y coordinate
@@ -29,11 +37,14 @@ public interface BlockChangeDelegate {
* @param typeId New block ID
* @param data Block data
* @return true if the block was set successfully
* @deprecated Magic value
*/
@Deprecated
public boolean setRawTypeIdAndData(int x, int y, int z, int typeId, int data);
/**
* Set a block type at the specified coordinates.
* <p>
* This method cannot call World.setRawTypeId, a full update is needed.
*
* @param x X coordinate
@@ -41,11 +52,14 @@ public interface BlockChangeDelegate {
* @param z Z coordinate
* @param typeId New block ID
* @return true if the block was set successfully
* @deprecated Magic value
*/
@Deprecated
public boolean setTypeId(int x, int y, int z, int typeId);
/**
* Set a block type and data at the specified coordinates.
* <p>
* This method cannot call World.setRawTypeId, a full update is needed.
*
* @param x X coordinate
@@ -54,7 +68,9 @@ public interface BlockChangeDelegate {
* @param typeId New block ID
* @param data Block data
* @return true if the block was set successfully
* @deprecated Magic value
*/
@Deprecated
public boolean setTypeIdAndData(int x, int y, int z, int typeId, int data);
/**
@@ -64,7 +80,9 @@ public interface BlockChangeDelegate {
* @param y Y coordinate
* @param z Z coordinate
* @return The block ID
* @deprecated Magic value
*/
@Deprecated
public int getTypeId(int x, int y, int z);
/**

View File

@@ -1,6 +1,8 @@
package org.bukkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -8,6 +10,8 @@ import java.util.Set;
import java.util.UUID;
import java.util.logging.Logger;
import org.bukkit.Warning.WarningState;
import org.bukkit.command.CommandException;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.PluginCommand;
@@ -17,12 +21,15 @@ import org.bukkit.help.HelpMap;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemFactory;
import org.bukkit.inventory.Recipe;
import org.bukkit.map.MapView;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.ServicesManager;
import org.bukkit.plugin.messaging.Messenger;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scoreboard.ScoreboardManager;
import org.bukkit.util.CachedServerIcon;
import com.avaje.ebean.config.ServerConfig;
@@ -48,7 +55,7 @@ public final class Bukkit {
/**
* Attempts to set the {@link Server} singleton.
* <p />
* <p>
* This cannot be done if the Server is already set.
*
* @param server Server instance
@@ -62,307 +69,682 @@ public final class Bukkit {
server.getLogger().info("This server is running " + getName() + " version " + getVersion() + " (Implementing API version " + getBukkitVersion() + ")");
}
/**
* @see Server#getName()
*/
public static String getName() {
return server.getName();
}
/**
* @see Server#getVersion()
*/
public static String getVersion() {
return server.getVersion();
}
/**
* @see Server#getBukkitVersion()
*/
public static String getBukkitVersion() {
return server.getBukkitVersion();
}
public static Player[] getOnlinePlayers() {
/**
* This method exists for legacy reasons to provide backwards
* compatibility. It will not exist at runtime and should not be used
* under any circumstances.
*
* @Deprecated
* @see Server#_INVALID_getOnlinePlayers()
*/
@Deprecated
public static Player[] _INVALID_getOnlinePlayers() {
return server._INVALID_getOnlinePlayers();
}
/**
* @see Server#getOnlinePlayers()
*/
public static Collection<? extends Player> getOnlinePlayers() {
return server.getOnlinePlayers();
}
/**
* @see Server#getMaxPlayers()
*/
public static int getMaxPlayers() {
return server.getMaxPlayers();
}
/**
* @see Server#getPort()
*/
public static int getPort() {
return server.getPort();
}
/**
* @see Server#getViewDistance()
*/
public static int getViewDistance() {
return server.getViewDistance();
}
/**
* @see Server#getIp()
*/
public static String getIp() {
return server.getIp();
}
/**
* @see Server#getServerName()
*/
public static String getServerName() {
return server.getServerName();
}
/**
* @see Server#getServerId()
*/
public static String getServerId() {
return server.getServerId();
}
/**
* @see Server#getWorldType()
*/
public static String getWorldType() {
return server.getWorldType();
}
/**
* @see Server#getGenerateStructures()
*/
public static boolean getGenerateStructures() {
return server.getGenerateStructures();
}
/**
* @see Server#getAllowNether()
*/
public static boolean getAllowNether() {
return server.getAllowNether();
}
/**
* @see Server#hasWhitelist()
*/
public static boolean hasWhitelist() {
return server.hasWhitelist();
}
/**
* @see Server#broadcastMessage(String message)
*/
public static int broadcastMessage(String message) {
return server.broadcastMessage(message);
}
/**
* @see Server#getUpdateFolder()
*/
public static String getUpdateFolder() {
return server.getUpdateFolder();
}
/**
* @see Server#getPlayer(String name)
*/
@Deprecated
public static Player getPlayer(String name) {
return server.getPlayer(name);
}
/**
* @see Server#matchPlayer(String name)
*/
@Deprecated
public static List<Player> matchPlayer(String name) {
return server.matchPlayer(name);
}
/**
* @see Server#getPlayer(java.util.UUID)
*/
public static Player getPlayer(UUID id) {
return server.getPlayer(id);
}
/**
* @see Server#getPluginManager()
*/
public static PluginManager getPluginManager() {
return server.getPluginManager();
}
/**
* @see Server#getScheduler()
*/
public static BukkitScheduler getScheduler() {
return server.getScheduler();
}
/**
* @see Server#getServicesManager()
*/
public static ServicesManager getServicesManager() {
return server.getServicesManager();
}
/**
* @see Server#getWorlds()
*/
public static List<World> getWorlds() {
return server.getWorlds();
}
/**
* @see Server#createWorld(WorldCreator options)
*/
public static World createWorld(WorldCreator options) {
return server.createWorld(options);
}
/**
* @see Server#unloadWorld(String name, boolean save)
*/
public static boolean unloadWorld(String name, boolean save) {
return server.unloadWorld(name, save);
}
/**
* @see Server#unloadWorld(World world, boolean save)
*/
public static boolean unloadWorld(World world, boolean save) {
return server.unloadWorld(world, save);
}
/**
* @see Server#getWorld(String name)
*/
public static World getWorld(String name) {
return server.getWorld(name);
}
/**
* @see Server#getWorld(UUID uid)
*/
public static World getWorld(UUID uid) {
return server.getWorld(uid);
}
/**
* @see Server#getMap(short id)
* @deprecated Magic value
*/
@Deprecated
public static MapView getMap(short id) {
return server.getMap(id);
}
/**
* @see Server#createMap(World world)
*/
public static MapView createMap(World world) {
return server.createMap(world);
}
/**
* @see Server#reload()
*/
public static void reload() {
server.reload();
}
/**
* @see Server#getLogger()
*/
public static Logger getLogger() {
return server.getLogger();
}
/**
* @see Server#getPluginCommand(String name)
*/
public static PluginCommand getPluginCommand(String name) {
return server.getPluginCommand(name);
}
/**
* @see Server#savePlayers()
*/
public static void savePlayers() {
server.savePlayers();
}
public static boolean dispatchCommand(CommandSender sender, String commandLine) {
/**
* @see Server#dispatchCommand(CommandSender sender, String commandLine)
*/
public static boolean dispatchCommand(CommandSender sender, String commandLine) throws CommandException {
return server.dispatchCommand(sender, commandLine);
}
/**
* @see Server#configureDbConfig(ServerConfig config)
*/
public static void configureDbConfig(ServerConfig config) {
server.configureDbConfig(config);
}
/**
* @see Server#addRecipe(Recipe recipe)
*/
public static boolean addRecipe(Recipe recipe) {
return server.addRecipe(recipe);
}
/**
* @see Server#getRecipesFor(ItemStack result)
*/
public static List<Recipe> getRecipesFor(ItemStack result) {
return server.getRecipesFor(result);
}
/**
* @see Server#recipeIterator()
*/
public static Iterator<Recipe> recipeIterator() {
return server.recipeIterator();
}
/**
* @see Server#clearRecipes()
*/
public static void clearRecipes() {
server.clearRecipes();
}
/**
* @see Server#resetRecipes()
*/
public static void resetRecipes() {
server.resetRecipes();
}
/**
* @see Server#getCommandAliases()
*/
public static Map<String, String[]> getCommandAliases() {
return server.getCommandAliases();
}
/**
* @see Server#getSpawnRadius()
*/
public static int getSpawnRadius() {
return server.getSpawnRadius();
}
/**
* @see Server#setSpawnRadius(int value)
*/
public static void setSpawnRadius(int value) {
server.setSpawnRadius(value);
}
/**
* @see Server#getOnlineMode()
*/
public static boolean getOnlineMode() {
return server.getOnlineMode();
}
/**
* @see Server#getAllowFlight()
*/
public static boolean getAllowFlight() {
return server.getAllowFlight();
}
/**
* @see Server#isHardcore()
*/
public static boolean isHardcore() {
return server.isHardcore();
}
/**
* @see Server#shutdown()
*/
public static void shutdown() {
server.shutdown();
}
/**
* @see Server#broadcast(String message, String permission)
*/
public static int broadcast(String message, String permission) {
return server.broadcast(message, permission);
}
/**
* @see Server#getOfflinePlayer(String name)
*/
@Deprecated
public static OfflinePlayer getOfflinePlayer(String name) {
return server.getOfflinePlayer(name);
}
/**
* @see Server#getOfflinePlayer(java.util.UUID)
*/
public static OfflinePlayer getOfflinePlayer(UUID id) {
return server.getOfflinePlayer(id);
}
/**
* @see Server#getPlayerExact(String name)
*/
@Deprecated
public static Player getPlayerExact(String name) {
return server.getPlayerExact(name);
}
/**
* @see Server#getIPBans()
*/
public static Set<String> getIPBans() {
return server.getIPBans();
}
/**
* @see Server#banIP(String address)
*/
public static void banIP(String address) {
server.banIP(address);
}
/**
* @see Server#unbanIP(String address)
*/
public static void unbanIP(String address) {
server.unbanIP(address);
}
/**
* @see Server#getBannedPlayers()
*/
public static Set<OfflinePlayer> getBannedPlayers() {
return server.getBannedPlayers();
}
/**
* @see Server#getBanList(BanList.Type)
*/
public static BanList getBanList(BanList.Type type){
return server.getBanList(type);
}
/**
* @see Server#setWhitelist(boolean value)
*/
public static void setWhitelist(boolean value) {
server.setWhitelist(value);
}
/**
* @see Server#getWhitelistedPlayers()
*/
public static Set<OfflinePlayer> getWhitelistedPlayers() {
return server.getWhitelistedPlayers();
}
/**
* @see Server#reloadWhitelist()
*/
public static void reloadWhitelist() {
server.reloadWhitelist();
}
/**
* @see Server#getConsoleSender()
*/
public static ConsoleCommandSender getConsoleSender() {
return server.getConsoleSender();
}
/**
* @see Server#getOperators()
*/
public static Set<OfflinePlayer> getOperators() {
return server.getOperators();
}
/**
* @see Server#getWorldContainer()
*/
public static File getWorldContainer() {
return server.getWorldContainer();
}
/**
* @see Server#getMessenger()
*/
public static Messenger getMessenger() {
return server.getMessenger();
}
/**
* @see Server#getAllowEnd()
*/
public static boolean getAllowEnd() {
return server.getAllowEnd();
}
/**
* @see Server#getUpdateFolderFile()
*/
public static File getUpdateFolderFile() {
return server.getUpdateFolderFile();
}
/**
* @see Server#getConnectionThrottle()
*/
public static long getConnectionThrottle() {
return server.getConnectionThrottle();
}
/**
* @see Server#getTicksPerAnimalSpawns()
*/
public static int getTicksPerAnimalSpawns() {
return server.getTicksPerAnimalSpawns();
}
/**
* @see Server#getTicksPerMonsterSpawns()
*/
public static int getTicksPerMonsterSpawns() {
return server.getTicksPerMonsterSpawns();
}
/**
* @see Server#useExactLoginLocation()
*/
public static boolean useExactLoginLocation() {
return server.useExactLoginLocation();
}
/**
* @see Server#getDefaultGameMode()
*/
public static GameMode getDefaultGameMode() {
return server.getDefaultGameMode();
}
/**
* @see Server#setDefaultGameMode(GameMode mode)
*/
public static void setDefaultGameMode(GameMode mode) {
server.setDefaultGameMode(mode);
}
/**
* @see Server#getOfflinePlayers()
*/
public static OfflinePlayer[] getOfflinePlayers() {
return server.getOfflinePlayers();
}
/**
* @see Server#createInventory(InventoryHolder owner, InventoryType type)
*/
public static Inventory createInventory(InventoryHolder owner, InventoryType type) {
return server.createInventory(owner, type);
}
public static Inventory createInventory(InventoryHolder owner, int size) {
/**
* @see Server#createInventory(InventoryHolder owner, InventoryType type, String title)
*/
public static Inventory createInventory(InventoryHolder owner, InventoryType type, String title) {
return server.createInventory(owner, type, title);
}
/**
* @see Server#createInventory(InventoryHolder owner, int size)
*/
public static Inventory createInventory(InventoryHolder owner, int size) throws IllegalArgumentException {
return server.createInventory(owner, size);
}
public static Inventory createInventory(InventoryHolder owner, int size, String title) {
/**
* @see Server#createInventory(InventoryHolder owner, int size, String
* title)
*/
public static Inventory createInventory(InventoryHolder owner, int size, String title) throws IllegalArgumentException {
return server.createInventory(owner, size, title);
}
/**
* @see Server#getHelpMap()
*/
public static HelpMap getHelpMap() {
return server.getHelpMap();
}
/**
* @see Server#getMonsterSpawnLimit()
*/
public static int getMonsterSpawnLimit() {
return server.getMonsterSpawnLimit();
}
/**
* @see Server#getAnimalSpawnLimit()
*/
public static int getAnimalSpawnLimit() {
return server.getAnimalSpawnLimit();
}
/**
* @see Server#getWaterAnimalSpawnLimit()
*/
public static int getWaterAnimalSpawnLimit() {
return server.getWaterAnimalSpawnLimit();
}
/**
* @see Server#getAmbientSpawnLimit()
*/
public static int getAmbientSpawnLimit() {
return server.getAmbientSpawnLimit();
}
/**
* @see Server#isPrimaryThread()
*/
public static boolean isPrimaryThread() {
return server.isPrimaryThread();
}
/**
* @see Server#getMotd()
*/
public static String getMotd() {
return server.getMotd();
}
/**
* @see Server#getShutdownMessage()
*/
public static String getShutdownMessage() {
return server.getShutdownMessage();
}
/**
* @see Server#getWarningState()
*/
public static WarningState getWarningState() {
return server.getWarningState();
}
/**
* @see Server#getItemFactory()
*/
public static ItemFactory getItemFactory() {
return server.getItemFactory();
}
/**
* @see Server#getScoreboardManager()
*/
public static ScoreboardManager getScoreboardManager() {
return server.getScoreboardManager();
}
/**
* @see Server#getServerIcon()
*/
public static CachedServerIcon getServerIcon() {
return server.getServerIcon();
}
/**
* @see Server#loadServerIcon(File)
*/
public static CachedServerIcon loadServerIcon(File file) throws IllegalArgumentException, Exception {
return server.loadServerIcon(file);
}
/**
* @see Server#loadServerIcon(BufferedImage)
*/
public static CachedServerIcon loadServerIcon(BufferedImage image) throws IllegalArgumentException, Exception {
return server.loadServerIcon(image);
}
/**
* @see Server#setIdleTimeout(int)
*/
public static void setIdleTimeout(int threshold) {
server.setIdleTimeout(threshold);
}
/**
* @see Server#getIdleTimeout()
*/
public static int getIdleTimeout() {
return server.getIdleTimeout();
}
/**
* @see Server#getUnsafe()
*/
@Deprecated
public static UnsafeValues getUnsafe() {
return server.getUnsafe();
}
}

View File

@@ -101,8 +101,8 @@ public enum ChatColor {
RESET('r', 0x15);
/**
* The special character which prefixes all chat colour codes. Use this if you need to dynamically
* convert colour codes from your custom format.
* The special character which prefixes all chat colour codes. Use this if
* you need to dynamically convert colour codes from your custom format.
*/
public static final char COLOR_CHAR = '\u00A7';
private static final Pattern STRIP_COLOR_PATTERN = Pattern.compile("(?i)" + String.valueOf(COLOR_CHAR) + "[0-9A-FK-OR]");
@@ -157,7 +157,8 @@ public enum ChatColor {
* Gets the color represented by the specified color code
*
* @param code Code to check
* @return Associative {@link org.bukkit.ChatColor} with the given code, or null if it doesn't exist
* @return Associative {@link org.bukkit.ChatColor} with the given code,
* or null if it doesn't exist
*/
public static ChatColor getByChar(char code) {
return BY_CHAR.get(code);
@@ -167,7 +168,8 @@ public enum ChatColor {
* Gets the color represented by the specified color code
*
* @param code Code to check
* @return Associative {@link org.bukkit.ChatColor} with the given code, or null if it doesn't exist
* @return Associative {@link org.bukkit.ChatColor} with the given code,
* or null if it doesn't exist
*/
public static ChatColor getByChar(String code) {
Validate.notNull(code, "Code cannot be null");
@@ -191,12 +193,13 @@ public enum ChatColor {
}
/**
* Translates a string using an alternate color code character into a string that uses the internal
* ChatColor.COLOR_CODE color code character. The alternate color code character will only be replaced
* if it is immediately followed by 0-9, A-F, or a-f.
*
* Translates a string using an alternate color code character into a
* string that uses the internal ChatColor.COLOR_CODE color code
* character. The alternate color code character will only be replaced if
* it is immediately followed by 0-9, A-F, a-f, K-O, k-o, R or r.
*
* @param altColorChar The alternate color code character to replace. Ex: &
* @param textToTranslate Text containing the alternate color code character.
* @param textToTranslate Text containing the alternate color code character.
* @return Text containing the ChatColor.COLOR_CODE color code character.
*/
public static String translateAlternateColorCodes(char altColorChar, String textToTranslate) {
@@ -218,19 +221,21 @@ public enum ChatColor {
*/
public static String getLastColors(String input) {
String result = "";
int lastIndex = -1;
int length = input.length();
while ((lastIndex = input.indexOf(COLOR_CHAR, lastIndex + 1)) != -1) {
if (lastIndex < length - 1) {
char c = input.charAt(lastIndex + 1);
ChatColor col = getByChar(c);
// Search backwards from the end as it is faster
for (int index = length - 1; index > -1; index--) {
char section = input.charAt(index);
if (section == COLOR_CHAR && index < length - 1) {
char c = input.charAt(index + 1);
ChatColor color = getByChar(c);
if (col != null) {
if (col.isColor()) {
result = col.toString();
} else if (col.isFormat()) {
result += col.toString();
if (color != null) {
result = color.toString() + result;
// Once we find a color or reset we can stop searching
if (color.isColor() || color.equals(RESET)) {
break;
}
}
}

View File

@@ -50,9 +50,12 @@ public interface Chunk {
/**
* Capture thread-safe read-only snapshot of chunk data
*
* @param includeMaxblocky - if true, snapshot includes per-coordinate maximum Y values
* @param includeBiome - if true, snapshot includes per-coordinate biome type
* @param includeBiomeTempRain - if true, snapshot includes per-coordinate raw biome temperature and rainfall
* @param includeMaxblocky - if true, snapshot includes per-coordinate
* maximum Y values
* @param includeBiome - if true, snapshot includes per-coordinate biome
* type
* @param includeBiomeTempRain - if true, snapshot includes per-coordinate
* raw biome temperature and rainfall
* @return ChunkSnapshot
*/
ChunkSnapshot getChunkSnapshot(boolean includeMaxblocky, boolean includeBiome, boolean includeBiomeTempRain);
@@ -81,7 +84,8 @@ public interface Chunk {
/**
* Loads the chunk.
*
* @param generate Whether or not to generate a chunk if it doesn't already exist
* @param generate Whether or not to generate a chunk if it doesn't
* already exist
* @return true if the chunk has loaded successfully, otherwise false
*/
boolean load(boolean generate);
@@ -97,7 +101,8 @@ public interface Chunk {
* Unloads and optionally saves the Chunk
*
* @param save Controls whether the chunk is saved
* @param safe Controls whether to unload the chunk when players are nearby
* @param safe Controls whether to unload the chunk when players are
* nearby
* @return true if the chunk has unloaded successfully, otherwise false
*/
boolean unload(boolean save, boolean safe);

View File

@@ -3,8 +3,10 @@ package org.bukkit;
import org.bukkit.block.Biome;
/**
* Represents a static, thread-safe snapshot of chunk of blocks
* Purpose is to allow clean, efficient copy of a chunk data to be made, and then handed off for processing in another thread (e.g. map rendering)
* Represents a static, thread-safe snapshot of chunk of blocks.
* <p>
* Purpose is to allow clean, efficient copy of a chunk data to be made, and
* then handed off for processing in another thread (e.g. map rendering)
*/
public interface ChunkSnapshot {
@@ -36,7 +38,9 @@ public interface ChunkSnapshot {
* @param y 0-127
* @param z 0-15
* @return 0-255
* @deprecated Magic value
*/
@Deprecated
int getBlockTypeId(int x, int y, int z);
/**
@@ -46,7 +50,9 @@ public interface ChunkSnapshot {
* @param y 0-127
* @param z 0-15
* @return 0-15
* @deprecated Magic value
*/
@Deprecated
int getBlockData(int x, int y, int z);
/**
@@ -60,7 +66,8 @@ public interface ChunkSnapshot {
int getBlockSkyLight(int x, int y, int z);
/**
* Get light level emitted by block at corresponding coordinate in the chunk
* Get light level emitted by block at corresponding coordinate in the
* chunk
*
* @param x 0-15
* @param y 0-127
@@ -114,6 +121,7 @@ public interface ChunkSnapshot {
/**
* Test if section is empty
*
* @param sy - section Y coordinate (block Y / 16)
* @return true if empty, false if not
*/

View File

@@ -22,7 +22,9 @@ public enum CoalType {
* Gets the associated data value representing this type of coal
*
* @return A byte containing the data value of this coal type
* @deprecated Magic value
*/
@Deprecated
public byte getData() {
return data;
}
@@ -30,11 +32,12 @@ public enum CoalType {
/**
* Gets the type of coal with the given data value
*
* @param data
* Data value to fetch
* @param data Data value to fetch
* @return The {@link CoalType} representing the given value, or null if
* it doesn't exist
* it doesn't exist
* @deprecated Magic value
*/
@Deprecated
public static CoalType getByData(final byte data) {
return BY_DATA.get(data);
}

View File

@@ -0,0 +1,344 @@
package org.bukkit;
import java.util.Map;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs;
import com.google.common.collect.ImmutableMap;
/**
* A container for a color palette. This class is immutable; the set methods
* return a new color. The color names listed as fields are HTML4 standards,
* but subject to change.
*/
@SerializableAs("Color")
public final class Color implements ConfigurationSerializable {
private static final int BIT_MASK = 0xff;
/**
* White, or (0xFF,0xFF,0xFF) in (R,G,B)
*/
public static final Color WHITE = fromRGB(0xFFFFFF);
/**
* Silver, or (0xC0,0xC0,0xC0) in (R,G,B)
*/
public static final Color SILVER = fromRGB(0xC0C0C0);
/**
* Gray, or (0x80,0x80,0x80) in (R,G,B)
*/
public static final Color GRAY = fromRGB(0x808080);
/**
* Black, or (0x00,0x00,0x00) in (R,G,B)
*/
public static final Color BLACK = fromRGB(0x000000);
/**
* Red, or (0xFF,0x00,0x00) in (R,G,B)
*/
public static final Color RED = fromRGB(0xFF0000);
/**
* Maroon, or (0x80,0x00,0x00) in (R,G,B)
*/
public static final Color MAROON = fromRGB(0x800000);
/**
* Yellow, or (0xFF,0xFF,0x00) in (R,G,B)
*/
public static final Color YELLOW = fromRGB(0xFFFF00);
/**
* Olive, or (0x80,0x80,0x00) in (R,G,B)
*/
public static final Color OLIVE = fromRGB(0x808000);
/**
* Lime, or (0x00,0xFF,0x00) in (R,G,B)
*/
public static final Color LIME = fromRGB(0x00FF00);
/**
* Green, or (0x00,0x80,0x00) in (R,G,B)
*/
public static final Color GREEN = fromRGB(0x008000);
/**
* Aqua, or (0x00,0xFF,0xFF) in (R,G,B)
*/
public static final Color AQUA = fromRGB(0x00FFFF);
/**
* Teal, or (0x00,0x80,0x80) in (R,G,B)
*/
public static final Color TEAL = fromRGB(0x008080);
/**
* Blue, or (0x00,0x00,0xFF) in (R,G,B)
*/
public static final Color BLUE = fromRGB(0x0000FF);
/**
* Navy, or (0x00,0x00,0x80) in (R,G,B)
*/
public static final Color NAVY = fromRGB(0x000080);
/**
* Fuchsia, or (0xFF,0x00,0xFF) in (R,G,B)
*/
public static final Color FUCHSIA = fromRGB(0xFF00FF);
/**
* Purple, or (0x80,0x00,0x80) in (R,G,B)
*/
public static final Color PURPLE = fromRGB(0x800080);
/**
* Orange, or (0xFF,0xA5,0x00) in (R,G,B)
*/
public static final Color ORANGE = fromRGB(0xFFA500);
private final byte red;
private final byte green;
private final byte blue;
/**
* Creates a new Color object from a red, green, and blue
*
* @param red integer from 0-255
* @param green integer from 0-255
* @param blue integer from 0-255
* @return a new Color object for the red, green, blue
* @throws IllegalArgumentException if any value is strictly >255 or <0
*/
public static Color fromRGB(int red, int green, int blue) throws IllegalArgumentException {
return new Color(red, green, blue);
}
/**
* Creates a new Color object from a blue, green, and red
*
* @param blue integer from 0-255
* @param green integer from 0-255
* @param red integer from 0-255
* @return a new Color object for the red, green, blue
* @throws IllegalArgumentException if any value is strictly >255 or <0
*/
public static Color fromBGR(int blue, int green, int red) throws IllegalArgumentException {
return new Color(red, green, blue);
}
/**
* Creates a new color object from an integer that contains the red,
* green, and blue bytes in the lowest order 24 bits.
*
* @param rgb the integer storing the red, green, and blue values
* @return a new color object for specified values
* @throws IllegalArgumentException if any data is in the highest order 8
* bits
*/
public static Color fromRGB(int rgb) throws IllegalArgumentException {
Validate.isTrue((rgb >> 24) == 0, "Extrenuous data in: ", rgb);
return fromRGB(rgb >> 16 & BIT_MASK, rgb >> 8 & BIT_MASK, rgb >> 0 & BIT_MASK);
}
/**
* Creates a new color object from an integer that contains the blue,
* green, and red bytes in the lowest order 24 bits.
*
* @param bgr the integer storing the blue, green, and red values
* @return a new color object for specified values
* @throws IllegalArgumentException if any data is in the highest order 8
* bits
*/
public static Color fromBGR(int bgr) throws IllegalArgumentException {
Validate.isTrue((bgr >> 24) == 0, "Extrenuous data in: ", bgr);
return fromBGR(bgr >> 16 & BIT_MASK, bgr >> 8 & BIT_MASK, bgr >> 0 & BIT_MASK);
}
private Color(int red, int green, int blue) {
Validate.isTrue(red >= 0 && red <= BIT_MASK, "Red is not between 0-255: ", red);
Validate.isTrue(green >= 0 && green <= BIT_MASK, "Green is not between 0-255: ", green);
Validate.isTrue(blue >= 0 && blue <= BIT_MASK, "Blue is not between 0-255: ", blue);
this.red = (byte) red;
this.green = (byte) green;
this.blue = (byte) blue;
}
/**
* Gets the red component
*
* @return red component, from 0 to 255
*/
public int getRed() {
return BIT_MASK & red;
}
/**
* Creates a new Color object with specified component
*
* @param red the red component, from 0 to 255
* @return a new color object with the red component
*/
public Color setRed(int red) {
return fromRGB(red, getGreen(), getBlue());
}
/**
* Gets the green component
*
* @return green component, from 0 to 255
*/
public int getGreen() {
return BIT_MASK & green;
}
/**
* Creates a new Color object with specified component
*
* @param green the red component, from 0 to 255
* @return a new color object with the red component
*/
public Color setGreen(int green) {
return fromRGB(getRed(), green, getBlue());
}
/**
* Gets the blue component
*
* @return blue component, from 0 to 255
*/
public int getBlue() {
return BIT_MASK & blue;
}
/**
* Creates a new Color object with specified component
*
* @param blue the red component, from 0 to 255
* @return a new color object with the red component
*/
public Color setBlue(int blue) {
return fromRGB(getRed(), getGreen(), blue);
}
/**
*
* @return An integer representation of this color, as 0xRRGGBB
*/
public int asRGB() {
return getRed() << 16 | getGreen() << 8 | getBlue() << 0;
}
/**
*
* @return An integer representation of this color, as 0xBBGGRR
*/
public int asBGR() {
return getBlue() << 16 | getGreen() << 8 | getRed() << 0;
}
/**
* Creates a new color with its RGB components changed as if it was dyed
* with the colors passed in, replicating vanilla workbench dyeing
*
* @param colors The DyeColors to dye with
* @return A new color with the changed rgb components
*/
// TODO: Javadoc what this method does, not what it mimics. API != Implementation
public Color mixDyes(DyeColor... colors) {
Validate.noNullElements(colors, "Colors cannot be null");
Color[] toPass = new Color[colors.length];
for (int i = 0; i < colors.length; i++) {
toPass[i] = colors[i].getColor();
}
return mixColors(toPass);
}
/**
* Creates a new color with its RGB components changed as if it was dyed
* with the colors passed in, replicating vanilla workbench dyeing
*
* @param colors The colors to dye with
* @return A new color with the changed rgb components
*/
// TODO: Javadoc what this method does, not what it mimics. API != Implementation
public Color mixColors(Color... colors) {
Validate.noNullElements(colors, "Colors cannot be null");
int totalRed = this.getRed();
int totalGreen = this.getGreen();
int totalBlue = this.getBlue();
int totalMax = Math.max(Math.max(totalRed, totalGreen), totalBlue);
for (Color color : colors) {
totalRed += color.getRed();
totalGreen += color.getGreen();
totalBlue += color.getBlue();
totalMax += Math.max(Math.max(color.getRed(), color.getGreen()), color.getBlue());
}
float averageRed = totalRed / (colors.length + 1);
float averageGreen = totalGreen / (colors.length + 1);
float averageBlue = totalBlue / (colors.length + 1);
float averageMax = totalMax / (colors.length + 1);
float maximumOfAverages = Math.max(Math.max(averageRed, averageGreen), averageBlue);
float gainFactor = averageMax / maximumOfAverages;
return Color.fromRGB((int) (averageRed * gainFactor), (int) (averageGreen * gainFactor), (int) (averageBlue * gainFactor));
}
@Override
public boolean equals(Object o) {
if (!(o instanceof Color)) {
return false;
}
final Color that = (Color) o;
return this.blue == that.blue && this.green == that.green && this.red == that.red;
}
@Override
public int hashCode() {
return asRGB() ^ Color.class.hashCode();
}
public Map<String, Object> serialize() {
return ImmutableMap.<String, Object>of(
"RED", getRed(),
"BLUE", getBlue(),
"GREEN", getGreen()
);
}
@SuppressWarnings("javadoc")
public static Color deserialize(Map<String, Object> map) {
return fromRGB(
asInt("RED", map),
asInt("GREEN", map),
asInt("BLUE", map)
);
}
private static int asInt(String string, Map<String, Object> map) {
Object value = map.get(string);
if (value == null) {
throw new IllegalArgumentException(string + " not in map " + map);
}
if (!(value instanceof Number)) {
throw new IllegalArgumentException(string + '(' + value + ") is not a number");
}
return ((Number) value).intValue();
}
@Override
public String toString() {
return "Color:[rgb0x" + Integer.toHexString(getRed()).toUpperCase() + Integer.toHexString(getGreen()).toUpperCase() + Integer.toHexString(getBlue()).toUpperCase() + "]";
}
}

View File

@@ -53,7 +53,9 @@ public enum CropState {
* Gets the associated data value representing this growth state
*
* @return A byte containing the data value of this growth state
* @deprecated Magic value
*/
@Deprecated
public byte getData() {
return data;
}
@@ -61,11 +63,12 @@ public enum CropState {
/**
* Gets the CropState with the given data value
*
* @param data
* Data value to fetch
* @param data Data value to fetch
* @return The {@link CropState} representing the given value, or null if
* it doesn't exist
* it doesn't exist
* @deprecated Magic value
*/
@Deprecated
public static CropState getByData(final byte data) {
return BY_DATA.get(data);
}

View File

@@ -9,22 +9,27 @@ import com.google.common.collect.Maps;
*/
public enum Difficulty {
/**
* Players regain health over time, hostile mobs don't spawn, the hunger bar does not deplete.
* Players regain health over time, hostile mobs don't spawn, the hunger
* bar does not deplete.
*/
PEACEFUL(0),
/**
* Hostile mobs spawn, enemies deal less damage than on normal difficulty, the hunger bar does deplete and starving deals up to 5 hearts of damage. (Default value)
* Hostile mobs spawn, enemies deal less damage than on normal difficulty,
* the hunger bar does deplete and starving deals up to 5 hearts of
* damage. (Default value)
*/
EASY(1),
/**
* Hostile mobs spawn, enemies deal normal amounts of damage, the hunger bar does deplete and starving deals up to 9.5 hearts of damage.
* Hostile mobs spawn, enemies deal normal amounts of damage, the hunger
* bar does deplete and starving deals up to 9.5 hearts of damage.
*/
NORMAL(2),
/**
* Hostile mobs spawn, enemies deal greater damage than on normal difficulty, the hunger bar does deplete and starving can kill players.
* Hostile mobs spawn, enemies deal greater damage than on normal
* difficulty, the hunger bar does deplete and starving can kill players.
*/
HARD(3);
@@ -39,7 +44,9 @@ public enum Difficulty {
* Gets the difficulty value associated with this Difficulty.
*
* @return An integer value of this difficulty
* @deprecated Magic value
*/
@Deprecated
public int getValue() {
return value;
}
@@ -48,8 +55,11 @@ public enum Difficulty {
* Gets the Difficulty represented by the specified value
*
* @param value Value to check
* @return Associative {@link Difficulty} with the given value, or null if it doesn't exist
* @return Associative {@link Difficulty} with the given value, or null if
* it doesn't exist
* @deprecated Magic value
*/
@Deprecated
public static Difficulty getByValue(final int value) {
return BY_ID.get(value);
}

View File

@@ -2,7 +2,7 @@ package org.bukkit;
import java.util.Map;
import com.google.common.collect.Maps;
import com.google.common.collect.ImmutableMap;
/**
* All supported color values for dyes and cloth
@@ -10,99 +10,230 @@ import com.google.common.collect.Maps;
public enum DyeColor {
/**
* Represents white dye
* Represents white dye.
*/
WHITE(0x0),
WHITE(0x0, 0xF, Color.WHITE, Color.fromRGB(0xF0F0F0)),
/**
* Represents orange dye
* Represents orange dye.
*/
ORANGE(0x1),
ORANGE(0x1, 0xE, Color.fromRGB(0xD87F33), Color.fromRGB(0xEB8844)),
/**
* Represents magenta dye
* Represents magenta dye.
*/
MAGENTA(0x2),
MAGENTA(0x2, 0xD, Color.fromRGB(0xB24CD8), Color.fromRGB(0xC354CD)),
/**
* Represents light blue dye
* Represents light blue dye.
*/
LIGHT_BLUE(0x3),
LIGHT_BLUE(0x3, 0xC, Color.fromRGB(0x6699D8), Color.fromRGB(0x6689D3)),
/**
* Represents yellow dye
* Represents yellow dye.
*/
YELLOW(0x4),
YELLOW(0x4, 0xB, Color.fromRGB(0xE5E533), Color.fromRGB(0xDECF2A)),
/**
* Represents lime dye
* Represents lime dye.
*/
LIME(0x5),
LIME(0x5, 0xA, Color.fromRGB(0x7FCC19), Color.fromRGB(0x41CD34)),
/**
* Represents pink dye
* Represents pink dye.
*/
PINK(0x6),
PINK(0x6, 0x9, Color.fromRGB(0xF27FA5), Color.fromRGB(0xD88198)),
/**
* Represents gray dye
* Represents gray dye.
*/
GRAY(0x7),
GRAY(0x7, 0x8, Color.fromRGB(0x4C4C4C), Color.fromRGB(0x434343)),
/**
* Represents silver dye
* Represents silver dye.
*/
SILVER(0x8),
SILVER(0x8, 0x7, Color.fromRGB(0x999999), Color.fromRGB(0xABABAB)),
/**
* Represents cyan dye
* Represents cyan dye.
*/
CYAN(0x9),
CYAN(0x9, 0x6, Color.fromRGB(0x4C7F99), Color.fromRGB(0x287697)),
/**
* Represents purple dye
* Represents purple dye.
*/
PURPLE(0xA),
PURPLE(0xA, 0x5, Color.fromRGB(0x7F3FB2), Color.fromRGB(0x7B2FBE)),
/**
* Represents blue dye
* Represents blue dye.
*/
BLUE(0xB),
BLUE(0xB, 0x4, Color.fromRGB(0x334CB2), Color.fromRGB(0x253192)),
/**
* Represents brown dye
* Represents brown dye.
*/
BROWN(0xC),
BROWN(0xC, 0x3, Color.fromRGB(0x664C33), Color.fromRGB(0x51301A)),
/**
* Represents green dye
* Represents green dye.
*/
GREEN(0xD),
GREEN(0xD, 0x2, Color.fromRGB(0x667F33), Color.fromRGB(0x3B511A)),
/**
* Represents red dye
* Represents red dye.
*/
RED(0xE),
RED(0xE, 0x1, Color.fromRGB(0x993333), Color.fromRGB(0xB3312C)),
/**
* Represents black dye
* Represents black dye.
*/
BLACK(0xF);
BLACK(0xF, 0x0, Color.fromRGB(0x191919), Color.fromRGB(0x1E1B1B));
private final byte data;
private final static Map<Byte, DyeColor> BY_DATA = Maps.newHashMap();
private final byte woolData;
private final byte dyeData;
private final Color color;
private final Color firework;
private final static DyeColor[] BY_WOOL_DATA;
private final static DyeColor[] BY_DYE_DATA;
private final static Map<Color, DyeColor> BY_COLOR;
private final static Map<Color, DyeColor> BY_FIREWORK;
private DyeColor(final int data) {
this.data = (byte) data;
private DyeColor(final int woolData, final int dyeData, Color color, Color firework) {
this.woolData = (byte) woolData;
this.dyeData = (byte) dyeData;
this.color = color;
this.firework = firework;
}
/**
* Gets the associated data value representing this color
* Gets the associated (wool) data value representing this color.
*
* @return A byte containing the data value of this color
* @return A byte containing the (wool) data value of this color
* @deprecated The name is misleading. It would imply {@link
* Material#INK_SACK} but uses {@link Material#WOOL}
* @see #getWoolData()
* @see #getDyeData()
*/
@Deprecated
public byte getData() {
return data;
return getWoolData();
}
/**
* Gets the DyeColor with the given data value
* Gets the associated wool data value representing this color.
*
* @param data Data value to fetch
* @return The {@link DyeColor} representing the given value, or null if it doesn't exist
* @return A byte containing the wool data value of this color
* @see #getDyeData()
* @deprecated Magic value
*/
@Deprecated
public byte getWoolData() {
return woolData;
}
/**
* Gets the associated dye data value representing this color.
*
* @return A byte containing the dye data value of this color
* @see #getWoolData()
* @deprecated Magic value
*/
@Deprecated
public byte getDyeData() {
return dyeData;
}
/**
* Gets the color that this dye represents.
*
* @return The {@link Color} that this dye represents
*/
public Color getColor() {
return color;
}
/**
* Gets the firework color that this dye represents.
*
* @return The {@link Color} that this dye represents
*/
public Color getFireworkColor() {
return firework;
}
/**
* Gets the DyeColor with the given (wool) data value.
*
* @param data (wool) data value to fetch
* @return The {@link DyeColor} representing the given value, or null if
* it doesn't exist
* @deprecated The name is misleading. It would imply {@link
* Material#INK_SACK} but uses {@link Material#WOOL}
* @see #getByDyeData(byte)
* @see #getByWoolData(byte)
*/
@Deprecated
public static DyeColor getByData(final byte data) {
return BY_DATA.get(data);
return getByWoolData(data);
}
/**
* Gets the DyeColor with the given wool data value.
*
* @param data Wool data value to fetch
* @return The {@link DyeColor} representing the given value, or null if
* it doesn't exist
* @see #getByDyeData(byte)
* @deprecated Magic value
*/
@Deprecated
public static DyeColor getByWoolData(final byte data) {
int i = 0xff & data;
if (i >= BY_WOOL_DATA.length) {
return null;
}
return BY_WOOL_DATA[i];
}
/**
* Gets the DyeColor with the given dye data value.
*
* @param data Dye data value to fetch
* @return The {@link DyeColor} representing the given value, or null if
* it doesn't exist
* @see #getByWoolData(byte)
* @deprecated Magic value
*/
@Deprecated
public static DyeColor getByDyeData(final byte data) {
int i = 0xff & data;
if (i >= BY_DYE_DATA.length) {
return null;
}
return BY_DYE_DATA[i];
}
/**
* Gets the DyeColor with the given color value.
*
* @param color Color value to get the dye by
* @return The {@link DyeColor} representing the given value, or null if
* it doesn't exist
*/
public static DyeColor getByColor(final Color color) {
return BY_COLOR.get(color);
}
/**
* Gets the DyeColor with the given firework color value.
*
* @param color Color value to get dye by
* @return The {@link DyeColor} representing the given value, or null if
* it doesn't exist
*/
public static DyeColor getByFireworkColor(final Color color) {
return BY_FIREWORK.get(color);
}
static {
BY_WOOL_DATA = values();
BY_DYE_DATA = values();
ImmutableMap.Builder<Color, DyeColor> byColor = ImmutableMap.builder();
ImmutableMap.Builder<Color, DyeColor> byFirework = ImmutableMap.builder();
for (DyeColor color : values()) {
BY_DATA.put(color.getData(), color);
BY_WOOL_DATA[color.woolData & 0xff] = color;
BY_DYE_DATA[color.dyeData & 0xff] = color;
byColor.put(color.getColor(), color);
byFirework.put(color.getFireworkColor(), color);
}
BY_COLOR = byColor.build();
BY_FIREWORK = byFirework.build();
}
}

View File

@@ -64,11 +64,12 @@ public enum Effect {
*/
SMOKE(2000, Type.VISUAL, BlockFace.class),
/**
* Visual effect of a block breaking. Needs block ID as additional info.
* Sound of a block breaking. Needs block ID as additional info.
*/
STEP_SOUND(2001, Type.SOUND, Material.class),
/**
* Visual effect of a splash potion breaking. Needs potion data value as additional info.
* Visual effect of a splash potion breaking. Needs potion data value as
* additional info.
*/
POTION_BREAK(2002, Type.VISUAL, Potion.class),
/**
@@ -99,7 +100,9 @@ public enum Effect {
* Gets the ID for this effect.
*
* @return ID of this effect
* @deprecated Magic value
*/
@Deprecated
public int getId() {
return this.id;
}
@@ -112,7 +115,8 @@ public enum Effect {
}
/**
* @return The class which represents data for this effect, or null if none
* @return The class which represents data for this effect, or null if
* none
*/
public Class<?> getData() {
return this.data;
@@ -123,7 +127,9 @@ public enum Effect {
*
* @param id ID of the Effect to return
* @return Effect with the given ID
* @deprecated Magic value
*/
@Deprecated
public static Effect getById(int id) {
return BY_ID.get(id);
}

View File

@@ -45,7 +45,56 @@ public enum EntityEffect {
/**
* When a sheep eats a LONG_GRASS block.
*/
SHEEP_EAT(10);
SHEEP_EAT(10),
/**
* When an Iron Golem gives a rose.
* <p>
* This will not play an effect if the entity is not an iron golem.
*/
IRON_GOLEM_ROSE(11),
/**
* Hearts from a villager.
* <p>
* This will not play an effect if the entity is not a villager.
*/
VILLAGER_HEART(12),
/**
* When a villager is angry.
* <p>
* This will not play an effect if the entity is not a villager.
*/
VILLAGER_ANGRY(13),
/**
* Happy particles from a villager.
* <p>
* This will not play an effect if the entity is not a villager.
*/
VILLAGER_HAPPY(14),
/**
* Magic particles from a witch.
* <p>
* This will not play an effect if the entity is not a witch.
*/
WITCH_MAGIC(15),
/**
* When a zombie transforms into a villager by shaking violently.
* <p>
* This will not play an effect if the entity is not a zombie.
*/
ZOMBIE_TRANSFORM(16),
/**
* When a firework explodes.
* <p>
* This will not play an effect if the entity is not a firework.
*/
FIREWORK_EXPLODE(17);
private final byte data;
private final static Map<Byte, EntityEffect> BY_DATA = Maps.newHashMap();
@@ -58,7 +107,9 @@ public enum EntityEffect {
* Gets the data value of this EntityEffect
*
* @return The data value
* @deprecated Magic value
*/
@Deprecated
public byte getData() {
return data;
}
@@ -67,8 +118,11 @@ public enum EntityEffect {
* Gets the EntityEffect with the given data value
*
* @param data Data value to fetch
* @return The {@link EntityEffect} representing the given value, or null if it doesn't exist
* @return The {@link EntityEffect} representing the given value, or null
* if it doesn't exist
* @deprecated Magic value
*/
@Deprecated
public static EntityEffect getByData(final byte data) {
return BY_DATA.get(data);
}

View File

@@ -0,0 +1,421 @@
package org.bukkit;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.Validate;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.configuration.serialization.SerializableAs;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
/**
* Represents a single firework effect.
*/
@SerializableAs("Firework")
public final class FireworkEffect implements ConfigurationSerializable {
/**
* The type or shape of the effect.
*/
public enum Type {
/**
* A small ball effect.
*/
BALL,
/**
* A large ball effect.
*/
BALL_LARGE,
/**
* A star-shaped effect.
*/
STAR,
/**
* A burst effect.
*/
BURST,
/**
* A creeper-face effect.
*/
CREEPER,
;
}
/**
* Construct a firework effect.
*
* @return A utility object for building a firework effect
*/
public static Builder builder() {
return new Builder();
}
/**
* This is a builder for FireworkEffects.
*
* @see FireworkEffect#builder()
*/
public static final class Builder {
boolean flicker = false;
boolean trail = false;
final ImmutableList.Builder<Color> colors = ImmutableList.builder();
ImmutableList.Builder<Color> fadeColors = null;
Type type = Type.BALL;
Builder() {}
/**
* Specify the type of the firework effect.
*
* @param type The effect type
* @return This object, for chaining
* @throws IllegalArgumentException If type is null
*/
public Builder with(Type type) throws IllegalArgumentException {
Validate.notNull(type, "Cannot have null type");
this.type = type;
return this;
}
/**
* Add a flicker to the firework effect.
*
* @return This object, for chaining
*/
public Builder withFlicker() {
flicker = true;
return this;
}
/**
* Set whether the firework effect should flicker.
*
* @param flicker true if it should flicker, false if not
* @return This object, for chaining
*/
public Builder flicker(boolean flicker) {
this.flicker = flicker;
return this;
}
/**
* Add a trail to the firework effect.
*
* @return This object, for chaining
*/
public Builder withTrail() {
trail = true;
return this;
}
/**
* Set whether the firework effect should have a trail.
*
* @param trail true if it should have a trail, false for no trail
* @return This object, for chaining
*/
public Builder trail(boolean trail) {
this.trail = trail;
return this;
}
/**
* Add a primary color to the firework effect.
*
* @param color The color to add
* @return This object, for chaining
* @throws IllegalArgumentException If color is null
*/
public Builder withColor(Color color) throws IllegalArgumentException {
Validate.notNull(color, "Cannot have null color");
colors.add(color);
return this;
}
/**
* Add several primary colors to the firework effect.
*
* @param colors The colors to add
* @return This object, for chaining
* @throws IllegalArgumentException If colors is null
* @throws IllegalArgumentException If any color is null (may be
* thrown after changes have occurred)
*/
public Builder withColor(Color...colors) throws IllegalArgumentException {
Validate.notNull(colors, "Cannot have null colors");
if (colors.length == 0) {
return this;
}
ImmutableList.Builder<Color> list = this.colors;
for (Color color : colors) {
Validate.notNull(color, "Color cannot be null");
list.add(color);
}
return this;
}
/**
* Add several primary colors to the firework effect.
*
* @param colors An iterable object whose iterator yields the desired
* colors
* @return This object, for chaining
* @throws IllegalArgumentException If colors is null
* @throws IllegalArgumentException If any color is null (may be
* thrown after changes have occurred)
*/
public Builder withColor(Iterable<?> colors) throws IllegalArgumentException {
Validate.notNull(colors, "Cannot have null colors");
ImmutableList.Builder<Color> list = this.colors;
for (Object color : colors) {
if (!(color instanceof Color)) {
throw new IllegalArgumentException(color + " is not a Color in " + colors);
}
list.add((Color) color);
}
return this;
}
/**
* Add a fade color to the firework effect.
*
* @param color The color to add
* @return This object, for chaining
* @throws IllegalArgumentException If colors is null
* @throws IllegalArgumentException If any color is null (may be
* thrown after changes have occurred)
*/
public Builder withFade(Color color) throws IllegalArgumentException {
Validate.notNull(color, "Cannot have null color");
if (fadeColors == null) {
fadeColors = ImmutableList.builder();
}
fadeColors.add(color);
return this;
}
/**
* Add several fade colors to the firework effect.
*
* @param colors The colors to add
* @return This object, for chaining
* @throws IllegalArgumentException If colors is null
* @throws IllegalArgumentException If any color is null (may be
* thrown after changes have occurred)
*/
public Builder withFade(Color...colors) throws IllegalArgumentException {
Validate.notNull(colors, "Cannot have null colors");
if (colors.length == 0) {
return this;
}
ImmutableList.Builder<Color> list = this.fadeColors;
if (list == null) {
list = this.fadeColors = ImmutableList.builder();
}
for (Color color : colors) {
Validate.notNull(color, "Color cannot be null");
list.add(color);
}
return this;
}
/**
* Add several fade colors to the firework effect.
*
* @param colors An iterable object whose iterator yields the desired
* colors
* @return This object, for chaining
* @throws IllegalArgumentException If colors is null
* @throws IllegalArgumentException If any color is null (may be
* thrown after changes have occurred)
*/
public Builder withFade(Iterable<?> colors) throws IllegalArgumentException {
Validate.notNull(colors, "Cannot have null colors");
ImmutableList.Builder<Color> list = this.fadeColors;
if (list == null) {
list = this.fadeColors = ImmutableList.builder();
}
for (Object color : colors) {
if (!(color instanceof Color)) {
throw new IllegalArgumentException(color + " is not a Color in " + colors);
}
list.add((Color) color);
}
return this;
}
/**
* Create a {@link FireworkEffect} from the current contents of this
* builder.
* <p>
* To successfully build, you must have specified at least one color.
*
* @return The representative firework effect
*/
public FireworkEffect build() {
return new FireworkEffect(
flicker,
trail,
colors.build(),
fadeColors == null ? ImmutableList.<Color>of() : fadeColors.build(),
type
);
}
}
private static final String FLICKER = "flicker";
private static final String TRAIL = "trail";
private static final String COLORS = "colors";
private static final String FADE_COLORS = "fade-colors";
private static final String TYPE = "type";
private final boolean flicker;
private final boolean trail;
private final ImmutableList<Color> colors;
private final ImmutableList<Color> fadeColors;
private final Type type;
private String string = null;
FireworkEffect(boolean flicker, boolean trail, ImmutableList<Color> colors, ImmutableList<Color> fadeColors, Type type) {
if (colors.isEmpty()) {
throw new IllegalStateException("Cannot make FireworkEffect without any color");
}
this.flicker = flicker;
this.trail = trail;
this.colors = colors;
this.fadeColors = fadeColors;
this.type = type;
}
/**
* Get whether the firework effect flickers.
*
* @return true if it flickers, false if not
*/
public boolean hasFlicker() {
return flicker;
}
/**
* Get whether the firework effect has a trail.
*
* @return true if it has a trail, false if not
*/
public boolean hasTrail() {
return trail;
}
/**
* Get the primary colors of the firework effect.
*
* @return An immutable list of the primary colors
*/
public List<Color> getColors() {
return colors;
}
/**
* Get the fade colors of the firework effect.
*
* @return An immutable list of the fade colors
*/
public List<Color> getFadeColors() {
return fadeColors;
}
/**
* Get the type of the firework effect.
*
* @return The effect type
*/
public Type getType() {
return type;
}
/**
* @see ConfigurationSerializable
*/
public static ConfigurationSerializable deserialize(Map<String, Object> map) {
Type type = Type.valueOf((String) map.get(TYPE));
if (type == null) {
throw new IllegalArgumentException(map.get(TYPE) + " is not a valid Type");
}
return builder()
.flicker((Boolean) map.get(FLICKER))
.trail((Boolean) map.get(TRAIL))
.withColor((Iterable<?>) map.get(COLORS))
.withFade((Iterable<?>) map.get(FADE_COLORS))
.with(type)
.build();
}
public Map<String, Object> serialize() {
return ImmutableMap.<String, Object>of(
FLICKER, flicker,
TRAIL, trail,
COLORS, colors,
FADE_COLORS, fadeColors,
TYPE, type.name()
);
}
@Override
public String toString() {
final String string = this.string;
if (string == null) {
return this.string = "FireworkEffect:" + serialize();
}
return string;
}
@Override
public int hashCode() {
/**
* TRUE and FALSE as per boolean.hashCode()
*/
final int PRIME = 31, TRUE = 1231, FALSE = 1237;
int hash = 1;
hash = hash * PRIME + (flicker ? TRUE : FALSE);
hash = hash * PRIME + (trail ? TRUE : FALSE);
hash = hash * PRIME + type.hashCode();
hash = hash * PRIME + colors.hashCode();
hash = hash * PRIME + fadeColors.hashCode();
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof FireworkEffect)) {
return false;
}
FireworkEffect that = (FireworkEffect) obj;
return this.flicker == that.flicker
&& this.trail == that.trail
&& this.type == that.type
&& this.colors.equals(that.colors)
&& this.fadeColors.equals(that.fadeColors);
}
}

View File

@@ -7,18 +7,25 @@ import org.bukkit.entity.HumanEntity;
import com.google.common.collect.Maps;
/**
* Represents the various type of game modes that {@link HumanEntity}s may have
* Represents the various type of game modes that {@link HumanEntity}s may
* have
*/
public enum GameMode {
/**
* Creative mode may fly, build instantly, become invulnerable and create free items
* Creative mode may fly, build instantly, become invulnerable and create
* free items.
*/
CREATIVE(1),
/**
* Survival mode is the "normal" gameplay type, with no special features.
*/
SURVIVAL(0);
SURVIVAL(0),
/**
* Adventure mode cannot break blocks without the correct tools.
*/
ADVENTURE(2);
private final int value;
private final static Map<Integer, GameMode> BY_ID = Maps.newHashMap();
@@ -31,7 +38,9 @@ public enum GameMode {
* Gets the mode value associated with this GameMode
*
* @return An integer value of this gamemode
* @deprecated Magic value
*/
@Deprecated
public int getValue() {
return value;
}
@@ -40,8 +49,11 @@ public enum GameMode {
* Gets the GameMode represented by the specified value
*
* @param value Value to check
* @return Associative {@link GameMode} with the given value, or null if it doesn't exist
* @return Associative {@link GameMode} with the given value, or null if
* it doesn't exist
* @deprecated Magic value
*/
@Deprecated
public static GameMode getByValue(final int value) {
return BY_ID.get(value);
}

View File

@@ -33,7 +33,9 @@ public enum GrassSpecies {
* Gets the associated data value representing this species
*
* @return A byte containing the data value of this grass species
* @deprecated Magic value
*/
@Deprecated
public byte getData() {
return data;
}
@@ -41,11 +43,12 @@ public enum GrassSpecies {
/**
* Gets the GrassSpecies with the given data value
*
* @param data
* Data value to fetch
* @return The {@link GrassSpecies} representing the given value, or null if
* it doesn't exist
* @param data Data value to fetch
* @return The {@link GrassSpecies} representing the given value, or null
* if it doesn't exist
* @deprecated Magic value
*/
@Deprecated
public static GrassSpecies getByData(final byte data) {
return BY_DATA.get(data);
}

View File

@@ -11,19 +11,23 @@ public enum Instrument {
*/
PIANO(0x0),
/**
* Bass drum is normally played when a note block is on top of a stone-like block
* Bass drum is normally played when a note block is on top of a
* stone-like block
*/
BASS_DRUM(0x1),
/**
* Snare drum is normally played when a note block is on top of a sandy block.
* Snare drum is normally played when a note block is on top of a sandy
* block.
*/
SNARE_DRUM(0x2),
/**
* Sticks are normally played when a note block is on top of a glass block.
* Sticks are normally played when a note block is on top of a glass
* block.
*/
STICKS(0x3),
/**
* Bass guitar is normally played when a note block is on top of a wooden block.
* Bass guitar is normally played when a note block is on top of a wooden
* block.
*/
BASS_GUITAR(0x4);
@@ -36,16 +40,21 @@ public enum Instrument {
/**
* @return The type ID of this instrument.
* @deprecated Magic value
*/
@Deprecated
public byte getType() {
return this.type;
}
/**
* Get an instrument by its type ID.
*
* @param type The type ID
* @return The instrument
* @deprecated Magic value
*/
@Deprecated
public static Instrument getByType(final byte type) {
return BY_DATA.get(type);
}

View File

@@ -167,45 +167,79 @@ public class Location implements Cloneable {
}
/**
* Sets the yaw of this location
* Sets the yaw of this location, measured in degrees.
* <ul>
* <li>A yaw of 0 or 360 represents the positive z direction.
* <li>A yaw of 180 represents the negative z direction.
* <li>A yaw of 90 represents the negative x direction.
* <li>A yaw of 270 represents the positive x direction.
* </ul>
* Increasing yaw values are the equivalent of turning to your
* right-facing, increasing the scale of the next respective axis, and
* decreasing the scale of the previous axis.
*
* @param yaw New yaw
* @param yaw new rotation's yaw
*/
public void setYaw(float yaw) {
this.yaw = yaw;
}
/**
* Gets the yaw of this location
* Gets the yaw of this location, measured in degrees.
* <ul>
* <li>A yaw of 0 or 360 represents the positive z direction.
* <li>A yaw of 180 represents the negative z direction.
* <li>A yaw of 90 represents the negative x direction.
* <li>A yaw of 270 represents the positive x direction.
* </ul>
* Increasing yaw values are the equivalent of turning to your
* right-facing, increasing the scale of the next respective axis, and
* decreasing the scale of the previous axis.
*
* @return Yaw
* @return the rotation's yaw
*/
public float getYaw() {
return yaw;
}
/**
* Sets the pitch of this location
* Sets the pitch of this location, measured in degrees.
* <ul>
* <li>A pitch of 0 represents level forward facing.
* <li>A pitch of 90 represents downward facing, or negative y
* direction.
* <li>A pitch of -90 represents upward facing, or positive y direction.
* <ul>
* Increasing pitch values the equivalent of looking down.
*
* @param pitch New pitch
* @param pitch new incline's pitch
*/
public void setPitch(float pitch) {
this.pitch = pitch;
}
/**
* Gets the pitch of this location
* Gets the pitch of this location, measured in degrees.
* <ul>
* <li>A pitch of 0 represents level forward facing.
* <li>A pitch of 90 represents downward facing, or negative y
* direction.
* <li>A pitch of -90 represents upward facing, or positive y direction.
* <ul>
* Increasing pitch values the equivalent of looking down.
*
* @return Pitch
* @return the incline's pitch
*/
public float getPitch() {
return pitch;
}
/**
* Gets a Vector pointing in the direction that this Location is facing
* Gets a unit-vector pointing in the direction that this Location is
* facing.
*
* @return Vector
* @return a vector pointing the direction of this location's {@link
* #getPitch() pitch} and {@link #getYaw() yaw}
*/
public Vector getDirection() {
Vector vector = new Vector();
@@ -215,14 +249,47 @@ public class Location implements Cloneable {
vector.setY(-Math.sin(Math.toRadians(rotY)));
double h = Math.cos(Math.toRadians(rotY));
double xz = Math.cos(Math.toRadians(rotY));
vector.setX(-h * Math.sin(Math.toRadians(rotX)));
vector.setZ(h * Math.cos(Math.toRadians(rotX)));
vector.setX(-xz * Math.sin(Math.toRadians(rotX)));
vector.setZ(xz * Math.cos(Math.toRadians(rotX)));
return vector;
}
/**
* Sets the {@link #getYaw() yaw} and {@link #getPitch() pitch} to point
* in the direction of the vector.
*/
public Location setDirection(Vector vector) {
/*
* Sin = Opp / Hyp
* Cos = Adj / Hyp
* Tan = Opp / Adj
*
* x = -Opp
* z = Adj
*/
final double _2PI = 2 * Math.PI;
final double x = vector.getX();
final double z = vector.getZ();
if (x == 0 && z == 0) {
pitch = vector.getY() > 0 ? -90 : 90;
return this;
}
double theta = Math.atan2(-x, z);
yaw = (float) Math.toDegrees((theta + _2PI) % _2PI);
double x2 = NumberConversions.square(x);
double z2 = NumberConversions.square(z);
double xz = Math.sqrt(x2 + z2);
pitch = (float) Math.toDegrees(Math.atan(-vector.getY() / xz));
return this;
}
/**
* Adds the location by another.
*
@@ -323,18 +390,18 @@ public class Location implements Cloneable {
}
/**
* Gets the magnitude of the location, defined as sqrt(x^2+y^2+z^2). The value
* of this method is not cached and uses a costly square-root function, so
* do not repeatedly call this method to get the location's magnitude. NaN
* will be returned if the inner result of the sqrt() function overflows,
* which will be caused if the length is too long. Not world-aware and
* orientation independent.
* Gets the magnitude of the location, defined as sqrt(x^2+y^2+z^2). The
* value of this method is not cached and uses a costly square-root
* function, so do not repeatedly call this method to get the location's
* magnitude. NaN will be returned if the inner result of the sqrt()
* function overflows, which will be caused if the length is too long. Not
* world-aware and orientation independent.
*
* @see Vector
* @return the magnitude
*/
public double length() {
return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2));
return Math.sqrt(NumberConversions.square(x) + NumberConversions.square(y) + NumberConversions.square(z));
}
/**
@@ -345,15 +412,15 @@ public class Location implements Cloneable {
* @return the magnitude
*/
public double lengthSquared() {
return Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2);
return NumberConversions.square(x) + NumberConversions.square(y) + NumberConversions.square(z);
}
/**
* Get the distance between this location and another. The value
* of this method is not cached and uses a costly square-root function, so
* do not repeatedly call this method to get the location's magnitude. NaN
* will be returned if the inner result of the sqrt() function overflows,
* which will be caused if the distance is too long.
* Get the distance between this location and another. The value of this
* method is not cached and uses a costly square-root function, so do not
* repeatedly call this method to get the location's magnitude. NaN will
* be returned if the inner result of the sqrt() function overflows, which
* will be caused if the distance is too long.
*
* @see Vector
* @param o The other location
@@ -381,12 +448,12 @@ public class Location implements Cloneable {
throw new IllegalArgumentException("Cannot measure distance between " + getWorld().getName() + " and " + o.getWorld().getName());
}
return Math.pow(x - o.x, 2) + Math.pow(y - o.y, 2) + Math.pow(z - o.z, 2);
return NumberConversions.square(x - o.x) + NumberConversions.square(y - o.y) + NumberConversions.square(z - o.z);
}
/**
* Performs scalar multiplication, multiplying all components with a scalar.
* Not world-aware.
* Performs scalar multiplication, multiplying all components with a
* scalar. Not world-aware.
*
* @param m The factor
* @see Vector
@@ -464,7 +531,8 @@ public class Location implements Cloneable {
/**
* Constructs a new {@link Vector} based on this Location
*
* @return New Vector containing the coordinates represented by this Location
* @return New Vector containing the coordinates represented by this
* Location
*/
public Vector toVector() {
return new Vector(x, y, z);
@@ -480,7 +548,8 @@ public class Location implements Cloneable {
}
/**
* Safely converts a double (location coordinate) to an int (block coordinate)
* Safely converts a double (location coordinate) to an int (block
* coordinate)
*
* @param loc Precise coordinate
* @return Block coordinate

View File

@@ -1,24 +1,68 @@
package org.bukkit;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang.Validate;
import org.bukkit.map.MapView;
import org.bukkit.material.*;
import org.bukkit.material.Bed;
import org.bukkit.material.Button;
import org.bukkit.material.Cake;
import org.bukkit.material.Cauldron;
import org.bukkit.material.Chest;
import org.bukkit.material.Coal;
import org.bukkit.material.CocoaPlant;
import org.bukkit.material.Command;
import org.bukkit.material.Crops;
import org.bukkit.material.DetectorRail;
import org.bukkit.material.Diode;
import org.bukkit.material.Dispenser;
import org.bukkit.material.Door;
import org.bukkit.material.Dye;
import org.bukkit.material.EnderChest;
import org.bukkit.material.FlowerPot;
import org.bukkit.material.Furnace;
import org.bukkit.material.Gate;
import org.bukkit.material.Ladder;
import org.bukkit.material.Lever;
import org.bukkit.material.LongGrass;
import org.bukkit.material.MaterialData;
import org.bukkit.material.MonsterEggs;
import org.bukkit.material.Mushroom;
import org.bukkit.material.NetherWarts;
import org.bukkit.material.PistonBaseMaterial;
import org.bukkit.material.PistonExtensionMaterial;
import org.bukkit.material.PoweredRail;
import org.bukkit.material.PressurePlate;
import org.bukkit.material.Pumpkin;
import org.bukkit.material.Rails;
import org.bukkit.material.RedstoneTorch;
import org.bukkit.material.RedstoneWire;
import org.bukkit.material.Sandstone;
import org.bukkit.material.Sign;
import org.bukkit.material.Skull;
import org.bukkit.material.SmoothBrick;
import org.bukkit.material.SpawnEgg;
import org.bukkit.material.Stairs;
import org.bukkit.material.Step;
import org.bukkit.material.Torch;
import org.bukkit.material.TrapDoor;
import org.bukkit.material.Tree;
import org.bukkit.material.Tripwire;
import org.bukkit.material.TripwireHook;
import org.bukkit.material.Vine;
import org.bukkit.material.WoodenStep;
import org.bukkit.material.Wool;
import org.bukkit.potion.Potion;
import org.bukkit.util.Java15Compat;
import com.google.common.collect.Maps;
/**
* An enum of all material ids accepted by the official server + client
* An enum of all material IDs accepted by the official server and client
*/
public enum Material {
AIR(0),
AIR(0, 0),
STONE(1),
GRASS(2),
DIRT(3),
@@ -72,7 +116,7 @@ public enum Material {
FIRE(51),
MOB_SPAWNER(52),
WOOD_STAIRS(53, Stairs.class),
CHEST(54),
CHEST(54, Chest.class),
REDSTONE_WIRE(55, RedstoneWire.class),
DIAMOND_ORE(56),
DIAMOND_BLOCK(57),
@@ -113,7 +157,9 @@ public enum Material {
CAKE_BLOCK(92, 64, Cake.class),
DIODE_BLOCK_OFF(93, Diode.class),
DIODE_BLOCK_ON(94, Diode.class),
@Deprecated
LOCKED_CHEST(95),
STAINED_GLASS(95),
TRAP_DOOR(96, TrapDoor.class),
MONSTER_EGGS(97, MonsterEggs.class),
SMOOTH_BRICK(98, SmoothBrick.class),
@@ -133,7 +179,7 @@ public enum Material {
NETHER_BRICK(112),
NETHER_FENCE(113),
NETHER_BRICK_STAIRS(114, Stairs.class),
NETHER_WARTS(115, MaterialData.class),
NETHER_WARTS(115, NetherWarts.class),
ENCHANTMENT_TABLE(116),
BREWING_STAND(117, MaterialData.class),
CAULDRON(118, Cauldron.class),
@@ -143,6 +189,52 @@ public enum Material {
DRAGON_EGG(122),
REDSTONE_LAMP_OFF(123),
REDSTONE_LAMP_ON(124),
WOOD_DOUBLE_STEP(125, WoodenStep.class),
WOOD_STEP(126, WoodenStep.class),
COCOA(127, CocoaPlant.class),
SANDSTONE_STAIRS(128, Stairs.class),
EMERALD_ORE(129),
ENDER_CHEST(130, EnderChest.class),
TRIPWIRE_HOOK(131, TripwireHook.class),
TRIPWIRE(132, Tripwire.class),
EMERALD_BLOCK(133),
SPRUCE_WOOD_STAIRS(134, Stairs.class),
BIRCH_WOOD_STAIRS(135, Stairs.class),
JUNGLE_WOOD_STAIRS(136, Stairs.class),
COMMAND(137, Command.class),
BEACON(138),
COBBLE_WALL(139),
FLOWER_POT(140, FlowerPot.class),
CARROT(141),
POTATO(142),
WOOD_BUTTON(143, Button.class),
SKULL(144, Skull.class),
ANVIL(145),
TRAPPED_CHEST(146),
GOLD_PLATE(147),
IRON_PLATE(148),
REDSTONE_COMPARATOR_OFF(149),
REDSTONE_COMPARATOR_ON(150),
DAYLIGHT_DETECTOR(151),
REDSTONE_BLOCK(152),
QUARTZ_ORE(153),
HOPPER(154),
QUARTZ_BLOCK(155),
QUARTZ_STAIRS(156, Stairs.class),
ACTIVATOR_RAIL(157, PoweredRail.class),
DROPPER(158, Dispenser.class),
STAINED_CLAY(159),
STAINED_GLASS_PANE(160),
LEAVES_2(161),
LOG_2(162),
ACACIA_STAIRS(163, Stairs.class),
DARK_OAK_STAIRS(164, Stairs.class),
HAY_BLOCK(170),
CARPET(171),
HARD_CLAY(172),
COAL_BLOCK(173),
PACKED_ICE(174),
DOUBLE_PLANT(175),
// ----- Item Separator -----
IRON_SPADE(256, 1, 250),
IRON_PICKAXE(257, 1, 250),
@@ -211,9 +303,9 @@ public enum Material {
GRILLED_PORK(320),
PAINTING(321),
GOLDEN_APPLE(322),
SIGN(323, 1),
SIGN(323, 16),
WOOD_DOOR(324, 1),
BUCKET(325, 1),
BUCKET(325, 16),
WATER_BUCKET(326, 1),
LAVA_BUCKET(327, 1),
MINECART(328, 1),
@@ -249,7 +341,7 @@ public enum Material {
/**
* @see MapView
*/
MAP(358, 1, MaterialData.class),
MAP(358, MaterialData.class),
SHEARS(359, 1, 238),
MELON(360),
PUMPKIN_SEEDS(361),
@@ -280,6 +372,35 @@ public enum Material {
MONSTER_EGG(383, 64, SpawnEgg.class),
EXP_BOTTLE(384, 64),
FIREBALL(385, 64),
BOOK_AND_QUILL(386, 1),
WRITTEN_BOOK(387, 16),
EMERALD(388, 64),
ITEM_FRAME(389),
FLOWER_POT_ITEM(390),
CARROT_ITEM(391),
POTATO_ITEM(392),
BAKED_POTATO(393),
POISONOUS_POTATO(394),
EMPTY_MAP(395),
GOLDEN_CARROT(396),
SKULL_ITEM(397),
CARROT_STICK(398, 1, 25),
NETHER_STAR(399),
PUMPKIN_PIE(400),
FIREWORK(401),
FIREWORK_CHARGE(402),
ENCHANTED_BOOK(403, 1),
REDSTONE_COMPARATOR(404),
NETHER_BRICK_ITEM(405),
QUARTZ(406),
EXPLOSIVE_MINECART(407, 1),
HOPPER_MINECART(408, 1),
IRON_BARDING(417, 1),
GOLD_BARDING(418, 1),
DIAMOND_BARDING(419, 1),
LEASH(420),
NAME_TAG(421),
COMMAND_MINECART(422, 1),
GOLD_RECORD(2256, 1),
GREEN_RECORD(2257, 1),
RECORD_3(2258, 1),
@@ -290,10 +411,12 @@ public enum Material {
RECORD_8(2263, 1),
RECORD_9(2264, 1),
RECORD_10(2265, 1),
RECORD_11(2266, 1);
RECORD_11(2266, 1),
RECORD_12(2267, 1),
;
private final int id;
private final Class<? extends MaterialData> data;
private final Constructor<? extends MaterialData> ctor;
private static Material[] byId = new Material[383];
private final static Map<String, Material> BY_NAME = Maps.newHashMap();
private final int maxStack;
@@ -304,11 +427,11 @@ public enum Material {
}
private Material(final int id, final int stack) {
this(id, stack, null);
this(id, stack, MaterialData.class);
}
private Material(final int id, final int stack, final int durability) {
this(id, stack, durability, null);
this(id, stack, durability, MaterialData.class);
}
private Material(final int id, final Class<? extends MaterialData> data) {
@@ -323,14 +446,23 @@ public enum Material {
this.id = id;
this.durability = (short) durability;
this.maxStack = stack;
this.data = data == null ? MaterialData.class : data;
// try to cache the constructor for this material
try {
this.ctor = data.getConstructor(int.class, byte.class);
} catch (NoSuchMethodException ex) {
throw new AssertionError(ex);
} catch (SecurityException ex) {
throw new AssertionError(ex);
}
}
/**
* Gets the item ID or block ID of this Material
*
* @return ID of this material
* @deprecated Magic value
*/
@Deprecated
public int getId() {
return id;
}
@@ -359,36 +491,33 @@ public enum Material {
* @return MaterialData associated with this Material
*/
public Class<? extends MaterialData> getData() {
return data;
return ctor.getDeclaringClass();
}
/**
* Constructs a new MaterialData relevant for this Material, with the given
* initial data
* Constructs a new MaterialData relevant for this Material, with the
* given initial data
*
* @param raw Initial data to construct the MaterialData with
* @return New MaterialData with the given data
* @deprecated Magic value
*/
@Deprecated
public MaterialData getNewData(final byte raw) {
try {
Constructor<? extends MaterialData> ctor = data.getConstructor(int.class, byte.class);
return ctor.newInstance(id, raw);
} catch (InstantiationException ex) {
Logger.getLogger(Material.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(Material.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(Material.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(Material.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchMethodException ex) {
Logger.getLogger(Material.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(Material.class.getName()).log(Level.SEVERE, null, ex);
final Throwable t = ex.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
if (t instanceof Error) {
throw (Error) t;
}
throw new AssertionError(t);
} catch (Throwable t) {
throw new AssertionError(t);
}
return null;
}
/**
@@ -406,22 +535,33 @@ public enum Material {
* @return true if this Material is edible.
*/
public boolean isEdible() {
return equals(Material.BREAD)
|| equals(Material.COOKIE)
|| equals(Material.MELON)
|| equals(Material.MUSHROOM_SOUP)
|| equals(Material.RAW_CHICKEN)
|| equals(Material.COOKED_CHICKEN)
|| equals(Material.RAW_BEEF)
|| equals(Material.COOKED_BEEF)
|| equals(Material.RAW_FISH)
|| equals(Material.COOKED_FISH)
|| equals(Material.PORK)
|| equals(Material.GRILLED_PORK)
|| equals(Material.APPLE)
|| equals(Material.GOLDEN_APPLE)
|| equals(Material.ROTTEN_FLESH)
|| equals(Material.SPIDER_EYE);
switch (this) {
case BREAD:
case CARROT_ITEM:
case BAKED_POTATO:
case POTATO_ITEM:
case POISONOUS_POTATO:
case GOLDEN_CARROT:
case PUMPKIN_PIE:
case COOKIE:
case MELON:
case MUSHROOM_SOUP:
case RAW_CHICKEN:
case COOKED_CHICKEN:
case RAW_BEEF:
case COOKED_BEEF:
case RAW_FISH:
case COOKED_FISH:
case PORK:
case GRILLED_PORK:
case APPLE:
case GOLDEN_APPLE:
case ROTTEN_FLESH:
case SPIDER_EYE:
return true;
default:
return false;
}
}
/**
@@ -429,9 +569,11 @@ public enum Material {
*
* @param id ID of the material to get
* @return Material if found, or null
* @deprecated Magic value
*/
@Deprecated
public static Material getMaterial(final int id) {
if (byId.length > id) {
if (byId.length > id && id >= 0) {
return byId[id];
} else {
return null;
@@ -440,6 +582,7 @@ public enum Material {
/**
* Attempts to get the Material with the given name.
* <p>
* This is a normal lookup, names must be the precise name they are given
* in the enum.
*
@@ -452,8 +595,12 @@ public enum Material {
/**
* Attempts to match the Material with the given name.
* This is a match lookup; names will be converted to uppercase, then stripped
* of special characters in an attempt to format it like the enum
* <p>
* This is a match lookup; names will be converted to uppercase, then
* stripped of special characters in an attempt to format it like the
* enum.
* <p>
* Using this for match by ID is deprecated.
*
* @param name Name of the material to get
* @return Material if found, or null
@@ -493,6 +640,395 @@ public enum Material {
* @return True if this material represents a playable music disk.
*/
public boolean isRecord() {
return id >= GOLD_RECORD.id && id <= RECORD_11.id;
return id >= GOLD_RECORD.id && id <= RECORD_12.id;
}
/**
* Check if the material is a block and solid (cannot be passed through by
* a player)
*
* @return True if this material is a block and solid
*/
public boolean isSolid() {
if (!isBlock() || id == 0) {
return false;
}
switch (this) {
case STONE:
case GRASS:
case DIRT:
case COBBLESTONE:
case WOOD:
case BEDROCK:
case SAND:
case GRAVEL:
case GOLD_ORE:
case IRON_ORE:
case COAL_ORE:
case LOG:
case LEAVES:
case SPONGE:
case GLASS:
case LAPIS_ORE:
case LAPIS_BLOCK:
case DISPENSER:
case SANDSTONE:
case NOTE_BLOCK:
case BED_BLOCK:
case PISTON_STICKY_BASE:
case PISTON_BASE:
case PISTON_EXTENSION:
case WOOL:
case PISTON_MOVING_PIECE:
case GOLD_BLOCK:
case IRON_BLOCK:
case DOUBLE_STEP:
case STEP:
case BRICK:
case TNT:
case BOOKSHELF:
case MOSSY_COBBLESTONE:
case OBSIDIAN:
case MOB_SPAWNER:
case WOOD_STAIRS:
case CHEST:
case DIAMOND_ORE:
case DIAMOND_BLOCK:
case WORKBENCH:
case SOIL:
case FURNACE:
case BURNING_FURNACE:
case SIGN_POST:
case WOODEN_DOOR:
case COBBLESTONE_STAIRS:
case WALL_SIGN:
case STONE_PLATE:
case IRON_DOOR_BLOCK:
case WOOD_PLATE:
case REDSTONE_ORE:
case GLOWING_REDSTONE_ORE:
case ICE:
case SNOW_BLOCK:
case CACTUS:
case CLAY:
case JUKEBOX:
case FENCE:
case PUMPKIN:
case NETHERRACK:
case SOUL_SAND:
case GLOWSTONE:
case JACK_O_LANTERN:
case CAKE_BLOCK:
case LOCKED_CHEST:
case STAINED_GLASS:
case TRAP_DOOR:
case MONSTER_EGGS:
case SMOOTH_BRICK:
case HUGE_MUSHROOM_1:
case HUGE_MUSHROOM_2:
case IRON_FENCE:
case THIN_GLASS:
case MELON_BLOCK:
case FENCE_GATE:
case BRICK_STAIRS:
case SMOOTH_STAIRS:
case MYCEL:
case NETHER_BRICK:
case NETHER_FENCE:
case NETHER_BRICK_STAIRS:
case ENCHANTMENT_TABLE:
case BREWING_STAND:
case CAULDRON:
case ENDER_PORTAL_FRAME:
case ENDER_STONE:
case DRAGON_EGG:
case REDSTONE_LAMP_OFF:
case REDSTONE_LAMP_ON:
case WOOD_DOUBLE_STEP:
case WOOD_STEP:
case SANDSTONE_STAIRS:
case EMERALD_ORE:
case ENDER_CHEST:
case EMERALD_BLOCK:
case SPRUCE_WOOD_STAIRS:
case BIRCH_WOOD_STAIRS:
case JUNGLE_WOOD_STAIRS:
case COMMAND:
case BEACON:
case COBBLE_WALL:
case ANVIL:
case TRAPPED_CHEST:
case GOLD_PLATE:
case IRON_PLATE:
case DAYLIGHT_DETECTOR:
case REDSTONE_BLOCK:
case QUARTZ_ORE:
case HOPPER:
case QUARTZ_BLOCK:
case QUARTZ_STAIRS:
case DROPPER:
case STAINED_CLAY:
case HAY_BLOCK:
case HARD_CLAY:
case COAL_BLOCK:
case STAINED_GLASS_PANE:
case LEAVES_2:
case LOG_2:
case ACACIA_STAIRS:
case DARK_OAK_STAIRS:
case PACKED_ICE:
return true;
default:
return false;
}
}
/**
* Check if the material is a block and does not block any light
*
* @return True if this material is a block and does not block any light
*/
public boolean isTransparent() {
if (!isBlock()) {
return false;
}
switch (this) {
case AIR:
case SAPLING:
case POWERED_RAIL:
case DETECTOR_RAIL:
case LONG_GRASS:
case DEAD_BUSH:
case YELLOW_FLOWER:
case RED_ROSE:
case BROWN_MUSHROOM:
case RED_MUSHROOM:
case TORCH:
case FIRE:
case REDSTONE_WIRE:
case CROPS:
case LADDER:
case RAILS:
case LEVER:
case REDSTONE_TORCH_OFF:
case REDSTONE_TORCH_ON:
case STONE_BUTTON:
case SNOW:
case SUGAR_CANE_BLOCK:
case PORTAL:
case DIODE_BLOCK_OFF:
case DIODE_BLOCK_ON:
case PUMPKIN_STEM:
case MELON_STEM:
case VINE:
case WATER_LILY:
case NETHER_WARTS:
case ENDER_PORTAL:
case COCOA:
case TRIPWIRE_HOOK:
case TRIPWIRE:
case FLOWER_POT:
case CARROT:
case POTATO:
case WOOD_BUTTON:
case SKULL:
case REDSTONE_COMPARATOR_OFF:
case REDSTONE_COMPARATOR_ON:
case ACTIVATOR_RAIL:
case CARPET:
case DOUBLE_PLANT:
return true;
default:
return false;
}
}
/**
* Check if the material is a block and can catch fire
*
* @return True if this material is a block and can catch fire
*/
public boolean isFlammable() {
if (!isBlock()) {
return false;
}
switch (this) {
case WOOD:
case LOG:
case LEAVES:
case NOTE_BLOCK:
case BED_BLOCK:
case LONG_GRASS:
case DEAD_BUSH:
case WOOL:
case TNT:
case BOOKSHELF:
case WOOD_STAIRS:
case CHEST:
case WORKBENCH:
case SIGN_POST:
case WOODEN_DOOR:
case WALL_SIGN:
case WOOD_PLATE:
case JUKEBOX:
case FENCE:
case TRAP_DOOR:
case HUGE_MUSHROOM_1:
case HUGE_MUSHROOM_2:
case VINE:
case FENCE_GATE:
case WOOD_DOUBLE_STEP:
case WOOD_STEP:
case SPRUCE_WOOD_STAIRS:
case BIRCH_WOOD_STAIRS:
case JUNGLE_WOOD_STAIRS:
case TRAPPED_CHEST:
case DAYLIGHT_DETECTOR:
case CARPET:
case LEAVES_2:
case LOG_2:
case ACACIA_STAIRS:
case DARK_OAK_STAIRS:
return true;
default:
return false;
}
}
/**
* Check if the material is a block and can burn away
*
* @return True if this material is a block and can burn away
*/
public boolean isBurnable() {
if (!isBlock()) {
return false;
}
switch (this) {
case WOOD:
case LOG:
case LEAVES:
case LONG_GRASS:
case WOOL:
case YELLOW_FLOWER:
case RED_ROSE:
case TNT:
case BOOKSHELF:
case WOOD_STAIRS:
case FENCE:
case VINE:
case WOOD_DOUBLE_STEP:
case WOOD_STEP:
case SPRUCE_WOOD_STAIRS:
case BIRCH_WOOD_STAIRS:
case JUNGLE_WOOD_STAIRS:
case HAY_BLOCK:
case COAL_BLOCK:
case LEAVES_2:
case LOG_2:
case CARPET:
case DOUBLE_PLANT:
return true;
default:
return false;
}
}
/**
* Check if the material is a block and completely blocks vision
*
* @return True if this material is a block and completely blocks vision
*/
public boolean isOccluding() {
if (!isBlock()) {
return false;
}
switch (this) {
case STONE:
case GRASS:
case DIRT:
case COBBLESTONE:
case WOOD:
case BEDROCK:
case SAND:
case GRAVEL:
case GOLD_ORE:
case IRON_ORE:
case COAL_ORE:
case LOG:
case SPONGE:
case LAPIS_ORE:
case LAPIS_BLOCK:
case DISPENSER:
case SANDSTONE:
case NOTE_BLOCK:
case WOOL:
case GOLD_BLOCK:
case IRON_BLOCK:
case DOUBLE_STEP:
case BRICK:
case BOOKSHELF:
case MOSSY_COBBLESTONE:
case OBSIDIAN:
case MOB_SPAWNER:
case DIAMOND_ORE:
case DIAMOND_BLOCK:
case WORKBENCH:
case FURNACE:
case BURNING_FURNACE:
case REDSTONE_ORE:
case GLOWING_REDSTONE_ORE:
case SNOW_BLOCK:
case CLAY:
case JUKEBOX:
case PUMPKIN:
case NETHERRACK:
case SOUL_SAND:
case JACK_O_LANTERN:
case MONSTER_EGGS:
case SMOOTH_BRICK:
case HUGE_MUSHROOM_1:
case HUGE_MUSHROOM_2:
case MELON_BLOCK:
case MYCEL:
case NETHER_BRICK:
case ENDER_PORTAL_FRAME:
case ENDER_STONE:
case REDSTONE_LAMP_OFF:
case REDSTONE_LAMP_ON:
case WOOD_DOUBLE_STEP:
case EMERALD_ORE:
case EMERALD_BLOCK:
case COMMAND:
case QUARTZ_ORE:
case QUARTZ_BLOCK:
case DROPPER:
case STAINED_CLAY:
case HAY_BLOCK:
case HARD_CLAY:
case COAL_BLOCK:
case LOG_2:
case PACKED_ICE:
return true;
default:
return false;
}
}
/**
* @return True if this material is affected by gravity.
*/
public boolean hasGravity() {
if (!isBlock()) {
return false;
}
switch (this) {
case SAND:
case GRAVEL:
case ANVIL:
return true;
default:
return false;
}
}
}

View File

@@ -0,0 +1,21 @@
package org.bukkit;
public enum NetherWartsState {
/**
* State when first seeded
*/
SEEDED,
/**
* First growth stage
*/
STAGE_ONE,
/**
* Second growth stage
*/
STAGE_TWO,
/**
* Ready to harvest
*/
RIPE;
}

View File

@@ -39,7 +39,9 @@ public class Note {
* Returns the not sharped id of this tone.
*
* @return the not sharped id of this tone.
* @deprecated Magic value
*/
@Deprecated
public byte getId() {
return getId(false);
}
@@ -51,7 +53,9 @@ public class Note {
*
* @param sharped Set to true to return the sharped id.
* @return the id of this tone.
* @deprecated Magic value
*/
@Deprecated
public byte getId(boolean sharped) {
byte id = (byte) (sharped && sharpable ? this.id + 1 : this.id);
@@ -72,8 +76,11 @@ public class Note {
*
* @param id the id of the tone.
* @return if the tone id is the sharped id of the tone.
* @throws IllegalArgumentException if neither the tone nor the semitone have the id.
* @throws IllegalArgumentException if neither the tone nor the
* semitone have the id.
* @deprecated Magic value
*/
@Deprecated
public boolean isSharped(byte id) {
if (id == getId(false)) {
return false;
@@ -90,7 +97,9 @@ public class Note {
*
* @param id the id of the tone.
* @return the tone to id.
* @deprecated Magic value
*/
@Deprecated
public static Tone getById(byte id) {
return BY_DATA.get(id);
}
@@ -113,8 +122,8 @@ public class Note {
/**
* Creates a new note.
*
* @param note Internal note id. {@link #getId()} always return this value.
* The value has to be in the interval [0;&nbsp;24].
* @param note Internal note id. {@link #getId()} always return this
* value. The value has to be in the interval [0;&nbsp;24].
*/
public Note(int note) {
Validate.isTrue(note >= 0 && note <= 24, "The note value has to be between 0 and 24.");
@@ -126,7 +135,8 @@ public class Note {
* Creates a new note.
*
* @param octave The octave where the note is in. Has to be 0 - 2.
* @param tone The tone within the octave. If the octave is 2 the note has to be F#.
* @param tone The tone within the octave. If the octave is 2 the note has
* to be F#.
* @param sharped Set if the tone is sharped (e.g. for F#).
*/
public Note(int octave, Tone tone, boolean sharped) {
@@ -158,7 +168,8 @@ public class Note {
* Creates a new note for a sharp tone, such as A-sharp.
*
* @param octave The octave where the note is in. Has to be 0 - 2.
* @param tone The tone within the octave. If the octave is 2 the note has to be F#.
* @param tone The tone within the octave. If the octave is 2 the note has
* to be F#.
* @return The new note.
*/
public static Note sharp(int octave, Tone tone) {
@@ -197,7 +208,9 @@ public class Note {
* Returns the internal id of this note.
*
* @return the internal id of this note.
* @deprecated Magic value
*/
@Deprecated
public byte getId() {
return note;
}

View File

@@ -1,11 +1,15 @@
package org.bukkit;
import java.util.Date;
import java.util.UUID;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.AnimalTamer;
import org.bukkit.entity.Player;
import org.bukkit.permissions.ServerOperator;
public interface OfflinePlayer extends ServerOperator, AnimalTamer, ConfigurationSerializable {
/**
* Checks if this player is currently online
*
@@ -15,11 +19,21 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
/**
* Returns the name of this player
* <p>
* Names are no longer unique past a single game session. For persistent storage
* it is recommended that you use {@link #getUniqueId()} instead.
*
* @return Player name
* @return Player name or null if we have not seen a name for this player yet
*/
public String getName();
/**
* Returns the UUID of this player
*
* @return Player UUID
*/
public UUID getUniqueId();
/**
* Checks if this player is banned or not
*
@@ -31,7 +45,11 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
* Bans or unbans this player
*
* @param banned true if banned
* @deprecated Use {@link org.bukkit.BanList#addBan(String, String, Date,
* String)} or {@link org.bukkit.BanList#pardon(String)} to enhance
* functionality
*/
@Deprecated
public void setBanned(boolean banned);
/**
@@ -59,20 +77,24 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
public Player getPlayer();
/**
* Gets the first date and time that this player was witnessed on this server.
* Gets the first date and time that this player was witnessed on this
* server.
* <p>
* If the player has never played before, this will return 0. Otherwise, it will be
* the amount of milliseconds since midnight, January 1, 1970 UTC.
* If the player has never played before, this will return 0. Otherwise,
* it will be the amount of milliseconds since midnight, January 1, 1970
* UTC.
*
* @return Date of first log-in for this player, or 0
*/
public long getFirstPlayed();
/**
* Gets the last date and time that this player was witnessed on this server.
* Gets the last date and time that this player was witnessed on this
* server.
* <p>
* If the player has never played before, this will return 0. Otherwise, it will be
* the amount of milliseconds since midnight, January 1, 1970 UTC.
* If the player has never played before, this will return 0. Otherwise,
* it will be the amount of milliseconds since midnight, January 1, 1970
* UTC.
*
* @return Date of last log-in for this player, or 0
*/
@@ -86,8 +108,8 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
public boolean hasPlayedBefore();
/**
* Gets the Location where the player will spawn at their bed, null if they
* have not slept in one or their current bed spawn is invalid.
* Gets the Location where the player will spawn at their bed, null if
* they have not slept in one or their current bed spawn is invalid.
*
* @return Bed Spawn Location if bed exists, otherwise null.
*/

View File

@@ -4,6 +4,7 @@ package org.bukkit;
* Represents various types of portals that can be made in a world.
*/
public enum PortalType {
/**
* This is a Nether portal, made of obsidian.
*/

View File

@@ -0,0 +1,47 @@
package org.bukkit;
/**
* An enum to specify a rotation based orientation, like that on a clock.
* <p>
* It represents how something is viewed, as opposed to cardinal directions.
*/
public enum Rotation {
/**
* No rotation
*/
NONE,
/**
* Rotated clockwise by 90 degrees
*/
CLOCKWISE,
/**
* Flipped upside-down, a 180 degree rotation
*/
FLIPPED,
/**
* Rotated counter-clockwise by 90 degrees
*/
COUNTER_CLOCKWISE,
;
private static final Rotation [] rotations = values();
/**
* Rotate clockwise by 90 degrees.
*
* @return the relative rotation
*/
public Rotation rotateClockwise() {
return rotations[(this.ordinal() + 1) & 0x3];
}
/**
* Rotate counter-clockwise by 90 degrees.
*
* @return the relative rotation
*/
public Rotation rotateCounterClockwise() {
return rotations[(this.ordinal() - 1) & 0x3];
}
}

View File

@@ -23,7 +23,9 @@ public enum SandstoneType {
* Gets the associated data value representing this type of sandstone
*
* @return A byte containing the data value of this sandstone type
* @deprecated Magic value
*/
@Deprecated
public byte getData() {
return data;
}
@@ -31,11 +33,12 @@ public enum SandstoneType {
/**
* Gets the type of sandstone with the given data value
*
* @param data
* Data value to fetch
* @return The {@link SandstoneType} representing the given value, or null if
* it doesn't exist
* @param data Data value to fetch
* @return The {@link SandstoneType} representing the given value, or null
* if it doesn't exist
* @deprecated Magic value
*/
@Deprecated
public static SandstoneType getByData(final byte data) {
return BY_DATA.get(data);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
package org.bukkit;
/**
* Represents the different types of skulls.
*/
public enum SkullType {
SKELETON,
WITHER,
ZOMBIE,
PLAYER,
CREEPER;
}

View File

@@ -0,0 +1,211 @@
package org.bukkit;
/**
* An Enum of Sounds the server is able to send to players.
* <p>
* WARNING: At any time, sounds may be added/removed from this Enum or even
* MineCraft itself! There is no guarantee the sounds will play. There is no
* guarantee values will not be removed from this Enum. As such, you should
* not depend on the ordinal values of this class.
*/
public enum Sound {
AMBIENCE_CAVE,
AMBIENCE_RAIN,
AMBIENCE_THUNDER,
ANVIL_BREAK,
ANVIL_LAND,
ANVIL_USE,
ARROW_HIT,
BURP,
CHEST_CLOSE,
CHEST_OPEN,
CLICK,
DOOR_CLOSE,
DOOR_OPEN,
DRINK,
EAT,
EXPLODE,
FALL_BIG,
FALL_SMALL,
FIRE,
FIRE_IGNITE,
FIZZ,
FUSE,
GLASS,
HURT_FLESH,
ITEM_BREAK,
ITEM_PICKUP,
LAVA,
LAVA_POP,
LEVEL_UP,
MINECART_BASE,
MINECART_INSIDE,
NOTE_BASS,
NOTE_PIANO,
NOTE_BASS_DRUM,
NOTE_STICKS,
NOTE_BASS_GUITAR,
NOTE_SNARE_DRUM,
NOTE_PLING,
ORB_PICKUP,
PISTON_EXTEND,
PISTON_RETRACT,
PORTAL,
PORTAL_TRAVEL,
PORTAL_TRIGGER,
SHOOT_ARROW,
SPLASH,
SPLASH2,
STEP_GRASS,
STEP_GRAVEL,
STEP_LADDER,
STEP_SAND,
STEP_SNOW,
STEP_STONE,
STEP_WOOD,
STEP_WOOL,
SWIM,
WATER,
WOOD_CLICK,
// Mob sounds
BAT_DEATH,
BAT_HURT,
BAT_IDLE,
BAT_LOOP,
BAT_TAKEOFF,
BLAZE_BREATH,
BLAZE_DEATH,
BLAZE_HIT,
CAT_HISS,
CAT_HIT,
CAT_MEOW,
CAT_PURR,
CAT_PURREOW,
CHICKEN_IDLE,
CHICKEN_HURT,
CHICKEN_EGG_POP,
CHICKEN_WALK,
COW_IDLE,
COW_HURT,
COW_WALK,
CREEPER_HISS,
CREEPER_DEATH,
ENDERDRAGON_DEATH,
ENDERDRAGON_GROWL,
ENDERDRAGON_HIT,
ENDERDRAGON_WINGS,
ENDERMAN_DEATH,
ENDERMAN_HIT,
ENDERMAN_IDLE,
ENDERMAN_TELEPORT,
ENDERMAN_SCREAM,
ENDERMAN_STARE,
GHAST_SCREAM,
GHAST_SCREAM2,
GHAST_CHARGE,
GHAST_DEATH,
GHAST_FIREBALL,
GHAST_MOAN,
IRONGOLEM_DEATH,
IRONGOLEM_HIT,
IRONGOLEM_THROW,
IRONGOLEM_WALK,
MAGMACUBE_WALK,
MAGMACUBE_WALK2,
MAGMACUBE_JUMP,
PIG_IDLE,
PIG_DEATH,
PIG_WALK,
SHEEP_IDLE,
SHEEP_SHEAR,
SHEEP_WALK,
SILVERFISH_HIT,
SILVERFISH_KILL,
SILVERFISH_IDLE,
SILVERFISH_WALK,
SKELETON_IDLE,
SKELETON_DEATH,
SKELETON_HURT,
SKELETON_WALK,
SLIME_ATTACK,
SLIME_WALK,
SLIME_WALK2,
SPIDER_IDLE,
SPIDER_DEATH,
SPIDER_WALK,
WITHER_DEATH,
WITHER_HURT,
WITHER_IDLE,
WITHER_SHOOT,
WITHER_SPAWN,
WOLF_BARK,
WOLF_DEATH,
WOLF_GROWL,
WOLF_HOWL,
WOLF_HURT,
WOLF_PANT,
WOLF_SHAKE,
WOLF_WALK,
WOLF_WHINE,
ZOMBIE_METAL,
ZOMBIE_WOOD,
ZOMBIE_WOODBREAK,
ZOMBIE_IDLE,
ZOMBIE_DEATH,
ZOMBIE_HURT,
ZOMBIE_INFECT,
ZOMBIE_UNFECT,
ZOMBIE_REMEDY,
ZOMBIE_WALK,
ZOMBIE_PIG_IDLE,
ZOMBIE_PIG_ANGRY,
ZOMBIE_PIG_DEATH,
ZOMBIE_PIG_HURT,
// Dig Sounds
DIG_WOOL,
DIG_GRASS,
DIG_GRAVEL,
DIG_SAND,
DIG_SNOW,
DIG_STONE,
DIG_WOOD,
// Fireworks
FIREWORK_BLAST,
FIREWORK_BLAST2,
FIREWORK_LARGE_BLAST,
FIREWORK_LARGE_BLAST2,
FIREWORK_TWINKLE,
FIREWORK_TWINKLE2,
FIREWORK_LAUNCH,
SUCCESSFUL_HIT,
// Horses
HORSE_ANGRY,
HORSE_ARMOR,
HORSE_BREATHE,
HORSE_DEATH,
HORSE_GALLOP,
HORSE_HIT,
HORSE_IDLE,
HORSE_JUMP,
HORSE_LAND,
HORSE_SADDLE,
HORSE_SOFT,
HORSE_WOOD,
DONKEY_ANGRY,
DONKEY_DEATH,
DONKEY_HIT,
DONKEY_IDLE,
HORSE_SKELETON_DEATH,
HORSE_SKELETON_HIT,
HORSE_SKELETON_IDLE,
HORSE_ZOMBIE_DEATH,
HORSE_ZOMBIE_HIT,
HORSE_ZOMBIE_IDLE,
// Villager
VILLAGER_DEATH,
VILLAGER_HAGGLE,
VILLAGER_HIT,
VILLAGER_IDLE,
VILLAGER_NO,
VILLAGER_YES,
}

View File

@@ -1,84 +1,108 @@
package org.bukkit;
import java.util.Map;
import com.google.common.collect.Maps;
/**
* Represents a countable statistic, which is collected by the client
* Represents a countable statistic, which is tracked by the server.
*/
public enum Statistic {
DAMAGE_DEALT(2020),
DAMAGE_TAKEN(2021),
DEATHS(2022),
MOB_KILLS(2023),
PLAYER_KILLS(2024),
FISH_CAUGHT(2025),
MINE_BLOCK(16777216, true),
USE_ITEM(6908288, false),
BREAK_ITEM(16973824, true);
DAMAGE_DEALT,
DAMAGE_TAKEN,
DEATHS,
MOB_KILLS,
PLAYER_KILLS,
FISH_CAUGHT,
ANIMALS_BRED,
TREASURE_FISHED,
JUNK_FISHED,
LEAVE_GAME,
JUMP,
DROP,
PLAY_ONE_TICK,
WALK_ONE_CM,
SWIM_ONE_CM,
FALL_ONE_CM,
CLIMB_ONE_CM,
FLY_ONE_CM,
DIVE_ONE_CM,
MINECART_ONE_CM,
BOAT_ONE_CM,
PIG_ONE_CM,
HORSE_ONE_CM,
MINE_BLOCK(Type.BLOCK),
USE_ITEM(Type.ITEM),
BREAK_ITEM(Type.ITEM),
CRAFT_ITEM(Type.ITEM),
KILL_ENTITY(Type.ENTITY),
ENTITY_KILLED_BY(Type.ENTITY);
private final static Map<Integer, Statistic> BY_ID = Maps.newHashMap();
private final int id;
private final boolean isSubstat;
private final boolean isBlock;
private final Type type;
private Statistic(int id) {
this(id, false, false);
private Statistic() {
this(Type.UNTYPED);
}
private Statistic(int id, boolean isBlock) {
this(id, true, isBlock);
}
private Statistic(int id, boolean isSubstat, boolean isBlock) {
this.id = id;
this.isSubstat = isSubstat;
this.isBlock = isBlock;
private Statistic(Type type) {
this.type = type;
}
/**
* Gets the ID for this statistic.
* Gets the type of this statistic.
*
* @return ID of this statistic
* @return the type of this statistic
*/
public int getId() {
return id;
public Type getType() {
return type;
}
/**
* Checks if this is a substatistic.
* <p />
* A substatistic exists in mass for each block or item, depending on {@link #isBlock()}
* <p>
* A substatistic exists en masse for each block, item, or entitytype, depending on
* {@link #getType()}.
* <p>
* This is a redundant method and equivalent to checking
* <code>getType() != Type.UNTYPED</code>
*
* @return true if this is a substatistic
*/
public boolean isSubstatistic() {
return isSubstat;
return type != Type.UNTYPED;
}
/**
* Checks if this is a substatistic dealing with blocks (As opposed to items)
* Checks if this is a substatistic dealing with blocks.
* <p>
* This is a redundant method and equivalent to checking
* <code>getType() == Type.BLOCK</code>
*
* @return true if this deals with blocks, false if with items
* @return true if this deals with blocks
*/
public boolean isBlock() {
return isSubstat && isBlock;
return type == Type.BLOCK;
}
/**
* Gets the statistic associated with the given ID.
* The type of statistic.
*
* @param id ID of the statistic to return
* @return statistic with the given ID
*/
public static Statistic getById(int id) {
return BY_ID.get(id);
}
public enum Type {
/**
* Statistics of this type do not require a qualifier.
*/
UNTYPED,
static {
for (Statistic statistic : values()) {
BY_ID.put(statistic.id, statistic);
}
/**
* Statistics of this type require an Item Material qualifier.
*/
ITEM,
/**
* Statistics of this type require a Block Material qualifier.
*/
BLOCK,
/**
* Statistics of this type require an EntityType qualifier.
*/
ENTITY;
}
}

View File

@@ -1,72 +1,94 @@
package org.bukkit;
/**
* The Travel Agent handles the creation and the research of Nether and End
* portals when Entities try to use one.
* <p>
* It is used in {@link org.bukkit.event.entity.EntityPortalEvent} and in
* {@link org.bukkit.event.player.PlayerPortalEvent} to help developers
* reproduce and/or modify Vanilla behaviour.
*/
public interface TravelAgent {
/**
* Set the Block radius to search in for available portals.
*
* @param radius The radius in which to search for a portal from the location.
* @return This travel agent.
* @param radius the radius in which to search for a portal from the
* location
* @return this travel agent
*/
public TravelAgent setSearchRadius(int radius);
/**
* Gets the search radius value for finding an available portal.
*
* @return Returns the currently set search radius.
* @return the currently set search radius
*/
public int getSearchRadius();
/**
* Sets the maximum radius from the given location to create a portal.
*
* @param radius The radius in which to create a portal from the location.
* @return This travel agent.
* @param radius the radius in which to create a portal from the location
* @return this travel agent
*/
public TravelAgent setCreationRadius(int radius);
/**
* Gets the maximum radius from the given location to create a portal.
*
* @return Returns the currently set creation radius.
* @return the currently set creation radius
*/
public int getCreationRadius();
/**
* Returns whether the TravelAgent will attempt to create a destination portal or not.
* Returns whether the TravelAgent will attempt to create a destination
* portal or not.
*
* @return Return whether the TravelAgent should create a destination portal or not.
* @return whether the TravelAgent should create a destination portal or
* not
*/
public boolean getCanCreatePortal();
/**
* Sets whether the TravelAgent should attempt to create a destination portal or not.
* Sets whether the TravelAgent should attempt to create a destination
* portal or not.
*
* @param create Sets whether the TravelAgent should create a destination portal or not.
* @param create Sets whether the TravelAgent should create a destination
* portal or not
*/
public void setCanCreatePortal(boolean create);
/**
* Attempt to find a portal near the given location, if a portal is not found it will attempt to create one.
* Attempt to find a portal near the given location, if a portal is not
* found it will attempt to create one.
*
* @param location The location where the search for a portal should begin.
* @return Returns the location of a portal which has been found or returns the location passed to the method if unsuccessful.
* @param location the location where the search for a portal should begin
* @return the location of a portal which has been found or returns the
* location passed to the method if unsuccessful
* @see #createPortal(Location)
*/
public Location findOrCreate(Location location);
/**
* Attempt to find a portal near the given location.
*
* @param location The desired location of the portal.
* @return Returns the location of the nearest portal to the location.
* @param location the desired location of the portal
* @return the location of the nearest portal to the location
*/
public Location findPortal(Location location);
/**
* Attempt to create a portal near the given location.
* <p>
* In the case of a Nether portal teleportation, this will attempt to
* create a Nether portal.
* <p>
* In the case of an Ender portal teleportation, this will (re-)create the
* obsidian platform and clean blocks above it.
*
* @param location The desired location of the portal.
* @return True if a nether portal was successfully created.
* @param location the desired location of the portal
* @return true if a portal was successfully created
*/
public boolean createPortal(Location location);
}
}

View File

@@ -24,7 +24,16 @@ public enum TreeSpecies {
/**
* Represents jungle trees.
*/
JUNGLE(0x3);
JUNGLE(0x3),
/**
* Represents acacia trees.
*/
ACACIA(0x4),
/**
* Represents dark oak trees.
*/
DARK_OAK(0x5),
;
private final byte data;
private final static Map<Byte, TreeSpecies> BY_DATA = Maps.newHashMap();
@@ -37,7 +46,9 @@ public enum TreeSpecies {
* Gets the associated data value representing this species
*
* @return A byte containing the data value of this tree species
* @deprecated Magic value
*/
@Deprecated
public byte getData() {
return data;
}
@@ -46,9 +57,11 @@ public enum TreeSpecies {
* Gets the TreeSpecies with the given data value
*
* @param data Data value to fetch
* @return The {@link TreeSpecies} representing the given value, or null if
* it doesn't exist
* @return The {@link TreeSpecies} representing the given value, or null
* if it doesn't exist
* @deprecated Magic value
*/
@Deprecated
public static TreeSpecies getByData(final byte data) {
return BY_DATA.get(data);
}

View File

@@ -4,6 +4,7 @@ package org.bukkit;
* Tree and organic structure types.
*/
public enum TreeType {
/**
* Regular tree, no branches
*/
@@ -32,6 +33,10 @@ public enum TreeType {
* Smaller jungle tree; 1 block wide
*/
SMALL_JUNGLE,
/**
* Jungle tree with cocoa plants; 1 block wide
*/
COCOA_TREE,
/**
* Small bush that grows in the jungle
*/
@@ -48,4 +53,20 @@ public enum TreeType {
* Swamp tree (regular with vines on the side)
*/
SWAMP,
/**
* Acacia tree.
*/
ACACIA,
/**
* Dark Oak tree.
*/
DARK_OAK,
/**
* Mega redwood tree; 4 blocks wide and tall
*/
MEGA_REDWOOD,
/**
* Tall birch tree
*/
TALL_BIRCH,
}

View File

@@ -0,0 +1,33 @@
package org.bukkit;
import java.util.List;
import org.bukkit.inventory.ItemStack;
/**
* This interface provides value conversions that may be specific to a
* runtime, or have arbitrary meaning (read: magic values).
* <p>
* Their existence and behavior is not guaranteed across future versions. They
* may be poorly named, throw exceptions, have misleading parameters, or any
* other bad programming practice.
* <p>
* This interface is unsupported and only for internal use.
*
* @deprecated Unsupported & internal use only
*/
@Deprecated
public interface UnsafeValues {
Material getMaterialFromInternalName(String name);
List<String> tabCompleteInternalMaterialName(String token, List<String> completions);
ItemStack modifyItemStack(ItemStack stack, String arguments);
Statistic getStatisticFromInternalName(String name);
Achievement getAchievementFromInternalName(String name);
List<String> tabCompleteInternalStatisticOrAchievementName(String token, List<String> completions);
}

View File

@@ -0,0 +1,18 @@
package org.bukkit;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* This annotation indicates a method (and sometimes constructor) will chain
* its internal operations.
* <p>
* This is solely meant for identifying methods that don't need to be
* overridden / handled manually.
*/
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface Utility {
}

View File

@@ -0,0 +1,109 @@
package org.bukkit;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Map;
import com.google.common.collect.ImmutableMap;
/**
* This designates the warning state for a specific item.
* <p>
* When the server settings dictate 'default' warnings, warnings are printed
* if the {@link #value()} is true.
*/
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Warning {
/**
* This represents the states that server verbose for warnings may be.
*/
public enum WarningState {
/**
* Indicates all warnings should be printed for deprecated items.
*/
ON,
/**
* Indicates no warnings should be printed for deprecated items.
*/
OFF,
/**
* Indicates each warning would default to the configured {@link
* Warning} annotation, or always if annotation not found.
*/
DEFAULT;
private static final Map<String, WarningState> values = ImmutableMap.<String,WarningState>builder()
.put("off", OFF)
.put("false", OFF)
.put("f", OFF)
.put("no", OFF)
.put("n", OFF)
.put("on", ON)
.put("true", ON)
.put("t", ON)
.put("yes", ON)
.put("y", ON)
.put("", DEFAULT)
.put("d", DEFAULT)
.put("default", DEFAULT)
.build();
/**
* This method checks the provided warning should be printed for this
* state
*
* @param warning The warning annotation added to a deprecated item
* @return <ul>
* <li>ON is always True
* <li>OFF is always false
* <li>DEFAULT is false if and only if annotation is not null and
* specifies false for {@link Warning#value()}, true otherwise.
* </ul>
*/
public boolean printFor(Warning warning) {
if (this == DEFAULT) {
return warning == null || warning.value();
}
return this == ON;
}
/**
* This method returns the corresponding warning state for the given
* string value.
*
* @param value The string value to check
* @return {@link #DEFAULT} if not found, or the respective
* WarningState
*/
public static WarningState value(final String value) {
if (value == null) {
return DEFAULT;
}
WarningState state = values.get(value.toLowerCase());
if (state == null) {
return DEFAULT;
}
return state;
}
}
/**
* This sets if the deprecation warnings when registering events gets
* printed when the setting is in the default state.
*
* @return false normally, or true to encourage warning printout
*/
boolean value() default false;
/**
* This can provide detailed information on why the event is deprecated.
*
* @return The reason an event is deprecated
*/
String reason() default "";
}

View File

@@ -0,0 +1,17 @@
package org.bukkit;
/**
* An enum of all current weather types
*/
public enum WeatherType {
/**
* Raining or snowing depending on biome.
*/
DOWNFALL,
/**
* Clear weather, clouds but no rain.
*/
CLEAR,
;
}

View File

@@ -29,7 +29,8 @@ public interface World extends PluginMessageRecipient, Metadatable {
* @param y Y-coordinate of the block
* @param z Z-coordinate of the block
* @return Block at the given coordinates
* @see #getBlockTypeIdAt(int, int, int) Returns the current type ID of the block
* @see #getBlockTypeIdAt(int, int, int) Returns the current type ID of
* the block
*/
public Block getBlockAt(int x, int y, int z);
@@ -38,7 +39,8 @@ public interface World extends PluginMessageRecipient, Metadatable {
*
* @param location Location of the block
* @return Block at the given location
* @see #getBlockTypeIdAt(org.bukkit.Location) Returns the current type ID of the block
* @see #getBlockTypeIdAt(org.bukkit.Location) Returns the current type ID
* of the block
*/
public Block getBlockAt(Location location);
@@ -49,8 +51,11 @@ public interface World extends PluginMessageRecipient, Metadatable {
* @param y Y-coordinate of the block
* @param z Z-coordinate of the block
* @return Type ID of the block at the given coordinates
* @see #getBlockAt(int, int, int) Returns a live Block object at the given location
* @see #getBlockAt(int, int, int) Returns a live Block object at the
* given location
* @deprecated Magic value
*/
@Deprecated
public int getBlockTypeIdAt(int x, int y, int z);
/**
@@ -58,8 +63,11 @@ public interface World extends PluginMessageRecipient, Metadatable {
*
* @param location Location of the block
* @return Type ID of the block at the given location
* @see #getBlockAt(org.bukkit.Location) Returns a live Block object at the given location
* @see #getBlockAt(org.bukkit.Location) Returns a live Block object at
* the given location
* @deprecated Magic value
*/
@Deprecated
public int getBlockTypeIdAt(Location location);
/**
@@ -152,11 +160,24 @@ public interface World extends PluginMessageRecipient, Metadatable {
*/
public boolean isChunkLoaded(int x, int z);
/**
* Checks if the {@link Chunk} at the specified coordinates is loaded and
* in use by one or more players
*
* @param x X-coordinate of the chunk
* @param z Z-coordinate of the chunk
* @return true if the chunk is loaded and in use by one or more players,
* otherwise false
*/
public boolean isChunkInUse(int x, int z);
/**
* Loads the {@link Chunk} at the specified coordinates
* <p />
* <p>
* If the chunk does not exist, it will be generated.
* This method is analogous to {@link #loadChunk(int, int, boolean)} where generate is true.
* <p>
* This method is analogous to {@link #loadChunk(int, int, boolean)} where
* generate is true.
*
* @param x X-coordinate of the chunk
* @param z Z-coordinate of the chunk
@@ -168,15 +189,17 @@ public interface World extends PluginMessageRecipient, Metadatable {
*
* @param x X-coordinate of the chunk
* @param z Z-coordinate of the chunk
* @param generate Whether or not to generate a chunk if it doesn't already exist
* @param generate Whether or not to generate a chunk if it doesn't
* already exist
* @return true if the chunk has loaded successfully, otherwise false
*/
public boolean loadChunk(int x, int z, boolean generate);
/**
* Safely unloads and saves the {@link Chunk} at the specified coordinates
* <p />
* This method is analogous to {@link #unloadChunk(int, int, boolean, boolean)} where safe and saveis true
* <p>
* This method is analogous to {@link #unloadChunk(int, int, boolean,
* boolean)} where safe and saveis true
*
* @param chunk the chunk to unload
* @return true if the chunk has unloaded successfully, otherwise false
@@ -185,8 +208,9 @@ public interface World extends PluginMessageRecipient, Metadatable {
/**
* Safely unloads and saves the {@link Chunk} at the specified coordinates
* <p />
* This method is analogous to {@link #unloadChunk(int, int, boolean, boolean)} where safe and saveis true
* <p>
* This method is analogous to {@link #unloadChunk(int, int, boolean,
* boolean)} where safe and saveis true
*
* @param x X-coordinate of the chunk
* @param z Z-coordinate of the chunk
@@ -195,9 +219,11 @@ public interface World extends PluginMessageRecipient, Metadatable {
public boolean unloadChunk(int x, int z);
/**
* Safely unloads and optionally saves the {@link Chunk} at the specified coordinates
* <p />
* This method is analogous to {@link #unloadChunk(int, int, boolean, boolean)} where save is true
* Safely unloads and optionally saves the {@link Chunk} at the specified
* coordinates
* <p>
* This method is analogous to {@link #unloadChunk(int, int, boolean,
* boolean)} where save is true
*
* @param x X-coordinate of the chunk
* @param z Z-coordinate of the chunk
@@ -207,20 +233,24 @@ public interface World extends PluginMessageRecipient, Metadatable {
public boolean unloadChunk(int x, int z, boolean save);
/**
* Unloads and optionally saves the {@link Chunk} at the specified coordinates
* Unloads and optionally saves the {@link Chunk} at the specified
* coordinates
*
* @param x X-coordinate of the chunk
* @param z Z-coordinate of the chunk
* @param save Controls whether the chunk is saved
* @param safe Controls whether to unload the chunk when players are nearby
* @param safe Controls whether to unload the chunk when players are
* nearby
* @return true if the chunk has unloaded successfully, otherwise false
*/
public boolean unloadChunk(int x, int z, boolean save, boolean safe);
/**
* Safely queues the {@link Chunk} at the specified coordinates for unloading
* <p />
* This method is analogous to {@link #unloadChunkRequest(int, int, boolean)} where safe is true
* Safely queues the {@link Chunk} at the specified coordinates for
* unloading
* <p>
* This method is analogous to {@link #unloadChunkRequest(int, int,
* boolean)} where safe is true
*
* @param x X-coordinate of the chunk
* @param z Z-coordinate of the chunk
@@ -278,12 +308,12 @@ public interface World extends PluginMessageRecipient, Metadatable {
* Creates an {@link Arrow} entity at the given {@link Location}
*
* @param location Location to spawn the arrow
* @param velocity Velocity to shoot the arrow in
* @param direction Direction to shoot the arrow in
* @param speed Speed of the arrow. A recommend speed is 0.6
* @param spread Spread of the arrow. A recommend spread is 12
* @return Arrow entity spawned as a result of this method
*/
public Arrow spawnArrow(Location location, Vector velocity, float speed, float spread);
public Arrow spawnArrow(Location location, Vector direction, float speed, float spread);
/**
* Creates a tree at the given {@link Location}
@@ -299,18 +329,32 @@ public interface World extends PluginMessageRecipient, Metadatable {
*
* @param loc Location to spawn the tree
* @param type Type of the tree to create
* @param delegate A class to call for each block changed as a result of this method
* @param delegate A class to call for each block changed as a result of
* this method
* @return true if the tree was created successfully, otherwise false
*/
public boolean generateTree(Location loc, TreeType type, BlockChangeDelegate delegate);
/**
* Creates a entity at the given {@link Location}
*
* @param loc The location to spawn the entity
* @param type The entity to spawn
* @return Resulting Entity of this method, or null if it was unsuccessful
*/
public Entity spawnEntity(Location loc, EntityType type);
/**
* Creates a creature at the given {@link Location}
*
* @param loc The location to spawn the creature
* @param type The creature to spawn
* @return Resulting LivingEntity of this method, or null if it was unsuccessful
* @return Resulting LivingEntity of this method, or null if it was
* unsuccessful
* @deprecated Has issues spawning non LivingEntities. Use {@link
* #spawnEntity(Location, EntityType) spawnEntity} instead.
*/
@Deprecated
public LivingEntity spawnCreature(Location loc, EntityType type);
/**
@@ -318,7 +362,8 @@ public interface World extends PluginMessageRecipient, Metadatable {
*
* @param loc The location to spawn the creature
* @param type The creature to spawn
* @return Resulting LivingEntity of this method, or null if it was unsuccessful
* @return Resulting LivingEntity of this method, or null if it was
* unsuccessful
*/
@Deprecated
public LivingEntity spawnCreature(Location loc, CreatureType type);
@@ -354,27 +399,33 @@ public interface World extends PluginMessageRecipient, Metadatable {
public List<LivingEntity> getLivingEntities();
/**
* Get a collection of all entities in this World matching the given class/interface
* Get a collection of all entities in this World matching the given
* class/interface
*
* @param classes The classes representing the types of entity to match
* @return A List of all Entities currently residing in this world that match the given class/interface
* @return A List of all Entities currently residing in this world that
* match the given class/interface
*/
@Deprecated
public <T extends Entity> Collection<T> getEntitiesByClass(Class<T>... classes);
/**
* Get a collection of all entities in this World matching the given class/interface
* Get a collection of all entities in this World matching the given
* class/interface
*
* @param cls The class representing the type of entity to match
* @return A List of all Entities currently residing in this world that match the given class/interface
* @return A List of all Entities currently residing in this world that
* match the given class/interface
*/
public <T extends Entity> Collection<T> getEntitiesByClass(Class<T> cls);
/**
* Get a collection of all entities in this World matching any of the given classes/interfaces
* Get a collection of all entities in this World matching any of the
* given classes/interfaces
*
* @param classes The classes representing the types of entity to match
* @return A List of all Entities currently residing in this world that match one or more of the given classes/interfaces
* @return A List of all Entities currently residing in this world that
* match one or more of the given classes/interfaces
*/
public Collection<Entity> getEntitiesByClasses(Class<?>... classes);
@@ -418,7 +469,7 @@ public interface World extends PluginMessageRecipient, Metadatable {
/**
* Gets the relative in-game time of this world.
* <p />
* <p>
* The relative time is analogous to hours * 1000
*
* @return The current relative time
@@ -428,14 +479,15 @@ public interface World extends PluginMessageRecipient, Metadatable {
/**
* Sets the relative in-game time on the server.
* <p />
* <p>
* The relative time is analogous to hours * 1000
* <br /><br />
* Note that setting the relative time below the current relative time will
* actually move the clock forward a day. If you require to rewind time, please
* see setFullTime
* <p>
* Note that setting the relative time below the current relative time
* will actually move the clock forward a day. If you require to rewind
* time, please see {@link #setFullTime(long)}
*
* @param time The new relative time to set the in-game time to (in hours*1000)
* @param time The new relative time to set the in-game time to (in
* hours*1000)
* @see #setFullTime(long) Sets the absolute time of this world
*/
public void setTime(long time);
@@ -450,7 +502,7 @@ public interface World extends PluginMessageRecipient, Metadatable {
/**
* Sets the in-game time on the server
* <br /><br />
* <p>
* Note that this sets the full time of the world, which may cause adverse
* effects such as breaking redstone clocks and any scheduled events
*
@@ -528,8 +580,8 @@ public interface World extends PluginMessageRecipient, Metadatable {
public boolean createExplosion(double x, double y, double z, float power);
/**
* Creates explosion at given coordinates with given power and optionally setting
* blocks on fire.
* Creates explosion at given coordinates with given power and optionally
* setting blocks on fire.
*
* @param x X coordinate
* @param y Y coordinate
@@ -540,6 +592,20 @@ public interface World extends PluginMessageRecipient, Metadatable {
*/
public boolean createExplosion(double x, double y, double z, float power, boolean setFire);
/**
* Creates explosion at given coordinates with given power and optionally
* setting blocks on fire or breaking blocks.
*
* @param x X coordinate
* @param y Y coordinate
* @param z Z coordinate
* @param power The power of explosion, where 4F is TNT
* @param setFire Whether or not to set blocks on fire
* @param breakBlocks Whether or not to have blocks be destroyed
* @return false if explosion was canceled, otherwise true
*/
public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks);
/**
* Creates explosion at given coordinates with given power
*
@@ -550,8 +616,8 @@ public interface World extends PluginMessageRecipient, Metadatable {
public boolean createExplosion(Location loc, float power);
/**
* Creates explosion at given coordinates with given power and optionally setting
* blocks on fire.
* Creates explosion at given coordinates with given power and optionally
* setting blocks on fire.
*
* @param loc Location to blow up
* @param power The power of explosion, where 4F is TNT
@@ -614,14 +680,52 @@ public interface World extends PluginMessageRecipient, Metadatable {
* @param clazz the class of the {@link Entity} to spawn
* @param <T> the class of the {@link Entity} to spawn
* @return an instance of the spawned {@link Entity}
* @throws IllegalArgumentException if either parameter is null or the {@link Entity} requested cannot be spawned
* @throws IllegalArgumentException if either parameter is null or the
* {@link Entity} requested cannot be spawned
*/
public <T extends Entity> T spawn(Location location, Class<T> clazz) throws IllegalArgumentException;
/**
* Plays an effect to all players within a default radius around a given location.
* Spawn a {@link FallingBlock} entity at the given {@link Location} of
* the specified {@link Material}. The material dictates what is falling.
* When the FallingBlock hits the ground, it will place that block.
* <p>
* The Material must be a block type, check with {@link Material#isBlock()
* material.isBlock()}. The Material may not be air.
*
* @param location the {@link Location} around which players must be to hear the sound
* @param location The {@link Location} to spawn the FallingBlock
* @param material The block {@link Material} type
* @param data The block data
* @return The spawned {@link FallingBlock} instance
* @throws IllegalArgumentException if {@link Location} or {@link
* Material} are null or {@link Material} is not a block
* @deprecated Magic value
*/
@Deprecated
public FallingBlock spawnFallingBlock(Location location, Material material, byte data) throws IllegalArgumentException;
/**
* Spawn a {@link FallingBlock} entity at the given {@link Location} of
* the specified blockId (converted to {@link Material})
*
* @param location The {@link Location} to spawn the FallingBlock
* @param blockId The id of the intended material
* @param blockData The block data
* @return The spawned FallingBlock instance
* @throws IllegalArgumentException if location is null, or blockId is
* invalid
* @see #spawnFallingBlock(org.bukkit.Location, org.bukkit.Material, byte)
* @deprecated Magic value
*/
@Deprecated
public FallingBlock spawnFallingBlock(Location location, int blockId, byte blockData) throws IllegalArgumentException;
/**
* Plays an effect to all players within a default radius around a given
* location.
*
* @param location the {@link Location} around which players must be to
* hear the sound
* @param effect the {@link Effect}
* @param data a data bit needed for some effects
*/
@@ -630,7 +734,8 @@ public interface World extends PluginMessageRecipient, Metadatable {
/**
* Plays an effect to all players within a given radius around a location.
*
* @param location the {@link Location} around which players must be to hear the effect
* @param location the {@link Location} around which players must be to
* hear the effect
* @param effect the {@link Effect}
* @param data a data bit needed for some effects
* @param radius the radius around the location
@@ -638,9 +743,11 @@ public interface World extends PluginMessageRecipient, Metadatable {
public void playEffect(Location location, Effect effect, int data, int radius);
/**
* Plays an effect to all players within a default radius around a given location.
* Plays an effect to all players within a default radius around a given
* location.
*
* @param location the {@link Location} around which players must be to hear the sound
* @param location the {@link Location} around which players must be to
* hear the sound
* @param effect the {@link Effect}
* @param data a data bit needed for some effects
*/
@@ -649,7 +756,8 @@ public interface World extends PluginMessageRecipient, Metadatable {
/**
* Plays an effect to all players within a given radius around a location.
*
* @param location the {@link Location} around which players must be to hear the effect
* @param location the {@link Location} around which players must be to
* hear the effect
* @param effect the {@link Effect}
* @param data a data bit needed for some effects
* @param radius the radius around the location
@@ -657,13 +765,16 @@ public interface World extends PluginMessageRecipient, Metadatable {
public <T> void playEffect(Location location, Effect effect, T data, int radius);
/**
* Get empty chunk snapshot (equivalent to all air blocks), optionally including valid biome
* data. Used for representing an ungenerated chunk, or for fetching only biome data without loading a chunk.
* Get empty chunk snapshot (equivalent to all air blocks), optionally
* including valid biome data. Used for representing an ungenerated chunk,
* or for fetching only biome data without loading a chunk.
*
* @param x - chunk x coordinate
* @param z - chunk z coordinate
* @param includeBiome - if true, snapshot includes per-coordinate biome type
* @param includeBiomeTempRain - if true, snapshot includes per-coordinate raw biome temperature and rainfall
* @param includeBiome - if true, snapshot includes per-coordinate biome
* type
* @param includeBiomeTempRain - if true, snapshot includes per-coordinate
* raw biome temperature and rainfall
* @return The empty snapshot.
*/
public ChunkSnapshot getEmptyChunkSnapshot(int x, int z, boolean includeBiome, boolean includeBiomeTempRain);
@@ -671,8 +782,10 @@ public interface World extends PluginMessageRecipient, Metadatable {
/**
* Sets the spawn flags for this.
*
* @param allowMonsters - if true, monsters are allowed to spawn in this world.
* @param allowAnimals - if true, animals are allowed to spawn in this world.
* @param allowMonsters - if true, monsters are allowed to spawn in this
* world.
* @param allowAnimals - if true, animals are allowed to spawn in this
* world.
*/
public void setSpawnFlags(boolean allowMonsters, boolean allowAnimals);
@@ -710,8 +823,9 @@ public interface World extends PluginMessageRecipient, Metadatable {
/**
* Gets the temperature for the given block coordinates.
* <p />
* It is safe to run this method when the block does not exist, it will not create the block.
* <p>
* It is safe to run this method when the block does not exist, it will
* not create the block.
*
* @param x X coordinate of the block
* @param z Z coordinate of the block
@@ -721,8 +835,9 @@ public interface World extends PluginMessageRecipient, Metadatable {
/**
* Gets the humidity for the given block coordinates.
* <p />
* It is safe to run this method when the block does not exist, it will not create the block.
* <p>
* It is safe to run this method when the block does not exist, it will
* not create the block.
*
* @param x X coordinate of the block
* @param z Z coordinate of the block
@@ -732,7 +847,7 @@ public interface World extends PluginMessageRecipient, Metadatable {
/**
* Gets the maximum height of this world.
* <p />
* <p>
* If the max height is 100, there are only blocks from y=0 to y=99.
*
* @return Maximum height of the world
@@ -741,7 +856,7 @@ public interface World extends PluginMessageRecipient, Metadatable {
/**
* Gets the sea level for this world.
* <p />
* <p>
* This is often half of {@link #getMaxHeight()}
*
* @return Sea level
@@ -749,16 +864,19 @@ public interface World extends PluginMessageRecipient, Metadatable {
public int getSeaLevel();
/**
* Gets whether the world's spawn area should be kept loaded into memory or not.
* Gets whether the world's spawn area should be kept loaded into memory
* or not.
*
* @return true if the world's spawn area will be kept loaded into memory.
*/
public boolean getKeepSpawnInMemory();
/**
* Sets whether the world's spawn area should be kept loaded into memory or not.
* Sets whether the world's spawn area should be kept loaded into memory
* or not.
*
* @param keepLoaded if true then the world's spawn area will be kept loaded into memory.
* @param keepLoaded if true then the world's spawn area will be kept
* loaded into memory.
*/
public void setKeepSpawnInMemory(boolean keepLoaded);
@@ -772,7 +890,8 @@ public interface World extends PluginMessageRecipient, Metadatable {
/**
* Sets whether or not the world will automatically save
*
* @param value true if the world should automatically save, otherwise false
* @param value true if the world should automatically save, otherwise
* false
*/
public void setAutoSave(boolean value);
@@ -813,19 +932,24 @@ public interface World extends PluginMessageRecipient, Metadatable {
/**
* Gets the world's ticks per animal spawns value
* <p />
* This value determines how many ticks there are between attempts to spawn animals.
* <p />
* <p>
* This value determines how many ticks there are between attempts to
* spawn animals.
* <p>
* <b>Example Usage:</b>
* <ul>
* <li>A value of 1 will mean the server will attempt to spawn animals in this world every tick.
* <li>A value of 400 will mean the server will attempt to spawn animals in this world every 400th tick.
* <li>A value of 1 will mean the server will attempt to spawn animals in
* this world every tick.
* <li>A value of 400 will mean the server will attempt to spawn animals
* in this world every 400th tick.
* <li>A value below 0 will be reset back to Minecraft's default.
* </ul>
* <p />
* <p>
* <b>Note:</b>
* If set to 0, animal spawning will be disabled for this world. We recommend using {@link #setSpawnFlags(boolean, boolean)} to control this instead.
* <p />
* If set to 0, animal spawning will be disabled for this world. We
* recommend using {@link #setSpawnFlags(boolean, boolean)} to control
* this instead.
* <p>
* Minecraft default: 400.
*
* @return The world's ticks per animal spawns value
@@ -834,40 +958,51 @@ public interface World extends PluginMessageRecipient, Metadatable {
/**
* Sets the world's ticks per animal spawns value
* <p />
* This value determines how many ticks there are between attempts to spawn animals.
* <p />
* <p>
* This value determines how many ticks there are between attempts to
* spawn animals.
* <p>
* <b>Example Usage:</b>
* <ul>
* <li>A value of 1 will mean the server will attempt to spawn animals in this world every tick.
* <li>A value of 400 will mean the server will attempt to spawn animals in this world every 400th tick.
* <li>A value of 1 will mean the server will attempt to spawn animals in
* this world every tick.
* <li>A value of 400 will mean the server will attempt to spawn animals
* in this world every 400th tick.
* <li>A value below 0 will be reset back to Minecraft's default.
* </ul>
* <p />
* <p>
* <b>Note:</b>
* If set to 0, animal spawning will be disabled for this world. We recommend using {@link #setSpawnFlags(boolean, boolean)} to control this instead.
* <p />
* If set to 0, animal spawning will be disabled for this world. We
* recommend using {@link #setSpawnFlags(boolean, boolean)} to control
* this instead.
* <p>
* Minecraft default: 400.
*
* @param ticksPerAnimalSpawns the ticks per animal spawns value you want to set the world to
* @param ticksPerAnimalSpawns the ticks per animal spawns value you want
* to set the world to
*/
public void setTicksPerAnimalSpawns(int ticksPerAnimalSpawns);
/**
* Gets the world's ticks per monster spawns value
* <p />
* This value determines how many ticks there are between attempts to spawn monsters.
* <p />
* <p>
* This value determines how many ticks there are between attempts to
* spawn monsters.
* <p>
* <b>Example Usage:</b>
* <ul>
* <li>A value of 1 will mean the server will attempt to spawn monsters in this world every tick.
* <li>A value of 400 will mean the server will attempt to spawn monsters in this world every 400th tick.
* <li>A value of 1 will mean the server will attempt to spawn monsters in
* this world every tick.
* <li>A value of 400 will mean the server will attempt to spawn monsters
* in this world every 400th tick.
* <li>A value below 0 will be reset back to Minecraft's default.
* </ul>
* <p />
* <p>
* <b>Note:</b>
* If set to 0, monsters spawning will be disabled for this world. We recommend using {@link #setSpawnFlags(boolean, boolean)} to control this instead.
* <p />
* If set to 0, monsters spawning will be disabled for this world. We
* recommend using {@link #setSpawnFlags(boolean, boolean)} to control
* this instead.
* <p>
* Minecraft default: 1.
*
* @return The world's ticks per monster spawns value
@@ -876,71 +1011,155 @@ public interface World extends PluginMessageRecipient, Metadatable {
/**
* Sets the world's ticks per monster spawns value
* <p />
* This value determines how many ticks there are between attempts to spawn monsters.
* <p />
* <p>
* This value determines how many ticks there are between attempts to
* spawn monsters.
* <p>
* <b>Example Usage:</b>
* <ul>
* <li>A value of 1 will mean the server will attempt to spawn monsters in this world on every tick.
* <li>A value of 400 will mean the server will attempt to spawn monsters in this world every 400th tick.
* <li>A value of 1 will mean the server will attempt to spawn monsters in
* this world on every tick.
* <li>A value of 400 will mean the server will attempt to spawn monsters
* in this world every 400th tick.
* <li>A value below 0 will be reset back to Minecraft's default.
* </ul>
* <p />
* <p>
* <b>Note:</b>
* If set to 0, monsters spawning will be disabled for this world. We recommend using {@link #setSpawnFlags(boolean, boolean)} to control this instead.
* <p />
* If set to 0, monsters spawning will be disabled for this world. We
* recommend using {@link #setSpawnFlags(boolean, boolean)} to control
* this instead.
* <p>
* Minecraft default: 1.
*
* @param ticksPerMonsterSpawns the ticks per monster spawns value you want to set the world to
* @param ticksPerMonsterSpawns the ticks per monster spawns value you
* want to set the world to
*/
public void setTicksPerMonsterSpawns(int ticksPerMonsterSpawns);
/**
* Gets limit for number of monsters that can spawn in a chunk in this world
* @returns The monster spawn limit
* Gets limit for number of monsters that can spawn in a chunk in this
* world
*
* @return The monster spawn limit
*/
int getMonsterSpawnLimit();
/**
* Sets the limit for number of monsters that can spawn in a chunk in this world
* <p />
* <b>Note:</b>
* If set to a negative number the world will use the server-wide spawn limit instead.
* Sets the limit for number of monsters that can spawn in a chunk in this
* world
* <p>
* <b>Note:</b> If set to a negative number the world will use the
* server-wide spawn limit instead.
*/
void setMonsterSpawnLimit(int limit);
/**
* Gets the limit for number of animals that can spawn in a chunk in this world
* @returns The animal spawn limit
* Gets the limit for number of animals that can spawn in a chunk in this
* world
*
* @return The animal spawn limit
*/
int getAnimalSpawnLimit();
/**
* Sets the limit for number of animals that can spawn in a chunk in this world
* <p />
* <b>Note:</b>
* If set to a negative number the world will use the server-wide spawn limit instead.
* Sets the limit for number of animals that can spawn in a chunk in this
* world
* <p>
* <b>Note:</b> If set to a negative number the world will use the
* server-wide spawn limit instead.
*/
void setAnimalSpawnLimit(int limit);
/**
* Gets the limit for number of water animals that can spawn in a chunk in this world
* @returns The water animal spawn limit
* Gets the limit for number of water animals that can spawn in a chunk in
* this world
*
* @return The water animal spawn limit
*/
int getWaterAnimalSpawnLimit();
/**
* Sets the limit for number of water animals that can spawn in a chunk in this world
* <p />
* <b>Note:</b>
* If set to a negative number the world will use the server-wide spawn limit instead.
* Sets the limit for number of water animals that can spawn in a chunk in
* this world
* <p>
* <b>Note:</b> If set to a negative number the world will use the
* server-wide spawn limit instead.
*/
void setWaterAnimalSpawnLimit(int limit);
/**
* Gets the limit for number of ambient mobs that can spawn in a chunk in
* this world
*
* @return The ambient spawn limit
*/
int getAmbientSpawnLimit();
/**
* Sets the limit for number of ambient mobs that can spawn in a chunk in
* this world
* <p>
* <b>Note:</b> If set to a negative number the world will use the
* server-wide spawn limit instead.
*/
void setAmbientSpawnLimit(int limit);
/**
* Play a Sound at the provided Location in the World
* <p>
* This function will fail silently if Location or Sound are null.
*
* @param location The location to play the sound
* @param sound The sound to play
* @param volume The volume of the sound
* @param pitch The pitch of the sound
*/
void playSound(Location location, Sound sound, float volume, float pitch);
/**
* Get existing rules
*
* @return An array of rules
*/
public String[] getGameRules();
/**
* Gets the current state of the specified rule
* <p>
* Will return null if rule passed is null
*
* @param rule Rule to look up value of
* @return String value of rule
*/
public String getGameRuleValue(String rule);
/**
* Set the specified gamerule to specified value.
* <p>
* The rule may attempt to validate the value passed, will return true if
* value was set.
* <p>
* If rule is null, the function will return false.
*
* @param rule Rule to set
* @param value Value to set rule to
* @return True if rule was set
*/
public boolean setGameRuleValue(String rule, String value);
/**
* Checks if string is a valid game rule
*
* @param rule Rule to check
* @return True if rule exists
*/
public boolean isGameRule(String rule);
/**
* Represents various map environment types that a world may be
*/
public enum Environment {
/**
* Represents the "normal"/"surface world" map
*/
@@ -965,16 +1184,21 @@ public interface World extends PluginMessageRecipient, Metadatable {
* Gets the dimension ID of this environment
*
* @return dimension ID
* @deprecated Magic value
*/
@Deprecated
public int getId() {
return id;
}
/**
* Get an environment by ID
*
* @param id The ID of the environment
* @return The environment
* @deprecated Magic value
*/
@Deprecated
public static Environment getEnvironment(int id) {
return lookup.get(id);
}

View File

@@ -141,8 +141,8 @@ public class WorldCreator {
/**
* Gets the generator that will be used to create or load the world.
* <p>
* This may be null, in which case the "natural" generator for this environment
* will be used.
* This may be null, in which case the "natural" generator for this
* environment will be used.
*
* @return Chunk generator
*/
@@ -153,8 +153,8 @@ public class WorldCreator {
/**
* Sets the generator that will be used to create or load the world.
* <p>
* This may be null, in which case the "natural" generator for this environment
* will be used.
* This may be null, in which case the "natural" generator for this
* environment will be used.
*
* @param generator Chunk generator
* @return This object, for chaining
@@ -168,11 +168,12 @@ public class WorldCreator {
/**
* Sets the generator that will be used to create or load the world.
* <p>
* This may be null, in which case the "natural" generator for this environment
* will be used.
* This may be null, in which case the "natural" generator for this
* environment will be used.
* <p>
* If the generator cannot be found for the given name, the natural environment generator
* will be used instead and a warning will be printed to the console.
* If the generator cannot be found for the given name, the natural
* environment generator will be used instead and a warning will be
* printed to the console.
*
* @param generator Name of the generator to use, in "plugin:id" notation
* @return This object, for chaining
@@ -186,14 +187,16 @@ public class WorldCreator {
/**
* Sets the generator that will be used to create or load the world.
* <p>
* This may be null, in which case the "natural" generator for this environment
* will be used.
* This may be null, in which case the "natural" generator for this
* environment will be used.
* <p>
* If the generator cannot be found for the given name, the natural environment generator
* will be used instead and a warning will be printed to the specified output
* If the generator cannot be found for the given name, the natural
* environment generator will be used instead and a warning will be
* printed to the specified output
*
* @param generator Name of the generator to use, in "plugin:id" notation
* @param output {@link CommandSender} that will receive any error messages
* @param output {@link CommandSender} that will receive any error
* messages
* @return This object, for chaining
*/
public WorldCreator generator(String generator, CommandSender output) {
@@ -203,7 +206,8 @@ public class WorldCreator {
}
/**
* Sets whether or not worlds created or loaded with this creator will have structures.
* Sets whether or not worlds created or loaded with this creator will
* have structures.
*
* @param generate Whether to generate structures
* @return This object, for chaining
@@ -226,8 +230,8 @@ public class WorldCreator {
/**
* Creates a world with the specified options.
* <p>
* If the world already exists, it will be loaded from disk and some options
* may be ignored.
* If the world already exists, it will be loaded from disk and some
* options may be ignored.
*
* @return Newly created or loaded world
*/
@@ -248,12 +252,13 @@ public class WorldCreator {
/**
* Attempts to get the {@link ChunkGenerator} with the given name.
* <p>
* If the generator is not found, null will be returned and a message will be
* printed to the specified {@link CommandSender} explaining why.
* If the generator is not found, null will be returned and a message will
* be printed to the specified {@link CommandSender} explaining why.
* <p>
* The name must be in the "plugin:id" notation, or optionally just "plugin",
* where "plugin" is the safe-name of a plugin and "id" is an optional unique
* identifier for the generator you wish to request from the plugin.
* The name must be in the "plugin:id" notation, or optionally just
* "plugin", where "plugin" is the safe-name of a plugin and "id" is an
* optional unique identifier for the generator you wish to request from
* the plugin.
*
* @param world Name of the world this will be used for
* @param name Name of the generator to retrieve

View File

@@ -9,7 +9,9 @@ import java.util.Map;
public enum WorldType {
NORMAL("DEFAULT"),
FLAT("FLAT"),
VERSION_1_1("DEFAULT_1_1");
VERSION_1_1("DEFAULT_1_1"),
LARGE_BIOMES("LARGEBIOMES"),
AMPLIFIED("AMPLIFIED");
private final static Map<String, WorldType> BY_NAME = Maps.newHashMap();
private final String name;

View File

@@ -0,0 +1,9 @@
package org.bukkit.block;
import org.bukkit.inventory.InventoryHolder;
/**
* Represents a beacon.
*/
public interface Beacon extends BlockState, InventoryHolder {
}

View File

@@ -4,17 +4,11 @@ package org.bukkit.block;
* Holds all accepted Biomes in the default server
*/
public enum Biome {
RAINFOREST,
SWAMPLAND,
SEASONAL_FOREST,
FOREST,
SAVANNA,
SHRUBLAND,
TAIGA,
DESERT,
PLAINS,
ICE_DESERT,
TUNDRA,
HELL,
SKY,
OCEAN,
@@ -32,5 +26,43 @@ public enum Biome {
TAIGA_HILLS,
SMALL_MOUNTAINS,
JUNGLE,
JUNGLE_HILLS
JUNGLE_HILLS,
JUNGLE_EDGE,
DEEP_OCEAN,
STONE_BEACH,
COLD_BEACH,
BIRCH_FOREST,
BIRCH_FOREST_HILLS,
ROOFED_FOREST,
COLD_TAIGA,
COLD_TAIGA_HILLS,
MEGA_TAIGA,
MEGA_TAIGA_HILLS,
EXTREME_HILLS_PLUS,
SAVANNA,
SAVANNA_PLATEAU,
MESA,
MESA_PLATEAU_FOREST,
MESA_PLATEAU,
SUNFLOWER_PLAINS,
DESERT_MOUNTAINS,
FLOWER_FOREST,
TAIGA_MOUNTAINS,
SWAMPLAND_MOUNTAINS,
ICE_PLAINS_SPIKES,
JUNGLE_MOUNTAINS,
JUNGLE_EDGE_MOUNTAINS,
COLD_TAIGA_MOUNTAINS,
SAVANNA_MOUNTAINS,
SAVANNA_PLATEAU_MOUNTAINS,
MESA_BRYCE,
MESA_PLATEAU_FOREST_MOUNTAINS,
MESA_PLATEAU_MOUNTAINS,
BIRCH_FOREST_MOUNTAINS,
BIRCH_FOREST_HILLS_MOUNTAINS,
ROOFED_FOREST_MOUNTAINS,
MEGA_SPRUCE_TAIGA,
EXTREME_HILLS_MOUNTAINS,
EXTREME_HILLS_PLUS_MOUNTAINS,
MEGA_SPRUCE_TAIGA_HILLS,
}

View File

@@ -11,9 +11,9 @@ import org.bukkit.metadata.Metadatable;
/**
* Represents a block. This is a live object, and only one Block may exist for
* any given location in a world. The state of the block may change concurrently
* to your own handling of it; use block.getState() to get a snapshot state of a
* block which will not be modified.
* any given location in a world. The state of the block may change
* concurrently to your own handling of it; use block.getState() to get a
* snapshot state of a block which will not be modified.
*/
public interface Block extends Metadatable {
@@ -21,7 +21,9 @@ public interface Block extends Metadatable {
* Gets the metadata for this block
*
* @return block specific metadata
* @deprecated Magic value
*/
@Deprecated
byte getData();
/**
@@ -35,8 +37,8 @@ public interface Block extends Metadatable {
Block getRelative(int modX, int modY, int modZ);
/**
* Gets the block at the given face<br />
* <br />
* Gets the block at the given face
* <p>
* This method is equal to getRelative(face, 1)
*
* @param face Face of this block to return
@@ -46,14 +48,14 @@ public interface Block extends Metadatable {
Block getRelative(BlockFace face);
/**
* Gets the block at the given distance of the given face<br />
* <br />
* For example, the following method places water at 100,102,100; two blocks
* above 100,100,100.
* Gets the block at the given distance of the given face
* <p>
* For example, the following method places water at 100,102,100; two
* blocks above 100,100,100.
*
* <pre>
* Block block = world.getBlockAt(100, 100, 100);
* Block shower = block.getFace(BlockFace.UP, 2);
* Block shower = block.getRelative(BlockFace.UP, 2);
* shower.setType(Material.WATER);
* </pre>
*
@@ -74,7 +76,9 @@ public interface Block extends Metadatable {
* Gets the type-id of this block
*
* @return block type-id
* @deprecated Magic value
*/
@Deprecated
int getTypeId();
/**
@@ -87,7 +91,8 @@ public interface Block extends Metadatable {
/**
* Get the amount of light at this block from the sky.
* <p>
* Any light given from other sources (such as blocks like torches) will be ignored.
* Any light given from other sources (such as blocks like torches) will
* be ignored.
*
* @return Sky light level
*/
@@ -137,6 +142,16 @@ public interface Block extends Metadatable {
*/
Location getLocation();
/**
* Stores the location of the block in the provided Location object.
* <p>
* If the provided Location is null this method does nothing and returns
* null.
*
* @return The Location object provided or null
*/
Location getLocation(Location loc);
/**
* Gets the chunk which contains this block
*
@@ -148,7 +163,9 @@ public interface Block extends Metadatable {
* Sets the metadata for this block
*
* @param data New block specific metadata
* @deprecated Magic value
*/
@Deprecated
void setData(byte data);
/**
@@ -156,7 +173,9 @@ public interface Block extends Metadatable {
*
* @param data New block specific metadata
* @param applyPhysics False to cancel physics from the changed block.
* @deprecated Magic value
*/
@Deprecated
void setData(byte data, boolean applyPhysics);
/**
@@ -171,7 +190,9 @@ public interface Block extends Metadatable {
*
* @param type Type-Id to change this block to
* @return whether the block was changed
* @deprecated Magic value
*/
@Deprecated
boolean setTypeId(int type);
/**
@@ -180,7 +201,9 @@ public interface Block extends Metadatable {
* @param type Type-Id to change this block to
* @param applyPhysics False to cancel physics on the changed block.
* @return whether the block was changed
* @deprecated Magic value
*/
@Deprecated
boolean setTypeId(int type, boolean applyPhysics);
/**
@@ -190,21 +213,21 @@ public interface Block extends Metadatable {
* @param data The data value to change this block to
* @param applyPhysics False to cancel physics on the changed block
* @return whether the block was changed
* @deprecated Magic value
*/
@Deprecated
boolean setTypeIdAndData(int type, byte data, boolean applyPhysics);
/**
* Gets the face relation of this block compared to the given block<br />
* <br />
* Gets the face relation of this block compared to the given block
* <p>
* For example:
*
* <pre>
* Block current = world.getBlockAt(100, 100, 100);
* Block target = world.getBlockAt(100, 101, 100);
*
* current.getFace(target) == BlockFace.Up;
* </pre>
*
* <br />
* If the given block is not connected to this block, null may be returned
*
@@ -216,9 +239,9 @@ public interface Block extends Metadatable {
/**
* Captures the current state of this block. You may then cast that state
* into any accepted type, such as Furnace or Sign.
* <p />
* The returned object will never be updated, and you are not guaranteed that
* (for example) a sign is still a sign after you capture its state.
* <p>
* The returned object will never be updated, and you are not guaranteed
* that (for example) a sign is still a sign after you capture its state.
*
* @return BlockState with the current state of this block.
*/
@@ -271,7 +294,8 @@ public interface Block extends Metadatable {
/**
* Returns the redstone power being provided to this block face
*
* @param face the face of the block to query or BlockFace.SELF for the block itself
* @param face the face of the block to query or BlockFace.SELF for the
* block itself
* @return The power level.
*/
int getBlockPower(BlockFace face);
@@ -285,8 +309,9 @@ public interface Block extends Metadatable {
/**
* Checks if this block is empty.
* <p />
* A block is considered empty when {@link #getType()} returns {@link Material#AIR}.
* <p>
* A block is considered empty when {@link #getType()} returns {@link
* Material#AIR}.
*
* @return true if this block is empty
*/
@@ -294,8 +319,10 @@ public interface Block extends Metadatable {
/**
* Checks if this block is liquid.
* <p />
* A block is considered liquid when {@link #getType()} returns {@link Material#WATER}, {@link Material#STATIONARY_WATER}, {@link Material#LAVA} or {@link Material#STATIONARY_LAVA}.
* <p>
* A block is considered liquid when {@link #getType()} returns {@link
* Material#WATER}, {@link Material#STATIONARY_WATER}, {@link
* Material#LAVA} or {@link Material#STATIONARY_LAVA}.
*
* @return true if this block is liquid
*/
@@ -330,7 +357,8 @@ public interface Block extends Metadatable {
boolean breakNaturally();
/**
* Breaks the block and spawns items as if a player had digged it with a specific tool
* Breaks the block and spawns items as if a player had digged it with a
* specific tool
*
* @param tool The tool or item in hand used for digging
* @return true if the block was destroyed
@@ -345,7 +373,8 @@ public interface Block extends Metadatable {
Collection<ItemStack> getDrops();
/**
* Returns a list of items which would drop by destroying this block with a specific tool
* Returns a list of items which would drop by destroying this block with
* a specific tool
*
* @param tool The tool or item in hand used for digging
* @return a list of dropped items for this type of block

View File

@@ -4,10 +4,10 @@ package org.bukkit.block;
* Represents the face of a block
*/
public enum BlockFace {
NORTH(-1, 0, 0),
EAST(0, 0, -1),
SOUTH(1, 0, 0),
WEST(0, 0, 1),
NORTH(0, 0, -1),
EAST(1, 0, 0),
SOUTH(0, 0, 1),
WEST(-1, 0, 0),
UP(0, 1, 0),
DOWN(0, -1, 0),
NORTH_EAST(NORTH, EAST),

View File

@@ -8,12 +8,13 @@ import org.bukkit.material.MaterialData;
import org.bukkit.metadata.Metadatable;
/**
* Represents a captured state of a block, which will not change automatically.
* <p />
* Unlike Block, which only one object can exist per coordinate, BlockState can
* exist multiple times for any given Block. Note that another plugin may change
* the state of the block and you will not know, or they may change the block to
* another type entirely, causing your BlockState to become invalid.
* Represents a captured state of a block, which will not change
* automatically.
* <p>
* Unlike Block, which only one object can exist per coordinate, BlockState
* can exist multiple times for any given Block. Note that another plugin may
* change the state of the block and you will not know, or they may change the
* block to another type entirely, causing your BlockState to become invalid.
*/
public interface BlockState extends Metadatable {
@@ -42,7 +43,9 @@ public interface BlockState extends Metadatable {
* Gets the type-id of this block
*
* @return block type-id
* @deprecated Magic value
*/
@Deprecated
int getTypeId();
/**
@@ -87,6 +90,16 @@ public interface BlockState extends Metadatable {
*/
Location getLocation();
/**
* Stores the location of this block in the provided Location object.
* <p>
* If the provided Location is null this method does nothing and returns
* null.
*
* @return The Location object provided or null
*/
Location getLocation(Location loc);
/**
* Gets the chunk which contains this block
*
@@ -113,13 +126,15 @@ public interface BlockState extends Metadatable {
*
* @param type Type-Id to change this block to
* @return Whether it worked?
* @deprecated Magic value
*/
@Deprecated
boolean setTypeId(int type);
/**
* Attempts to update the block represented by this state, setting it to the
* new values as defined by this state.
* <p />
* Attempts to update the block represented by this state, setting it to
* the new values as defined by this state.
* <p>
* This has the same effect as calling update(false). That is to say,
* this will not modify the state of a block if it is no longer the same
* type as it was when this state was taken. It will return false in this
@@ -131,15 +146,11 @@ public interface BlockState extends Metadatable {
boolean update();
/**
* Attempts to update the block represented by this state, setting it to the
* new values as defined by this state.
* <p />
* Unless force is true, this will not modify the state of a block if it is
* no longer the same type as it was when this state was taken. It will return
* false in this eventuality.
* <p />
* If force is true, it will set the type of the block to match the new state,
* set the state data and then return true.
* Attempts to update the block represented by this state, setting it to
* the new values as defined by this state.
* <p>
* This has the same effect as calling update(force, true). That is to
* say, this will trigger a physics update to surrounding blocks.
*
* @param force true to forcefully set the state
* @return true if the update was successful, otherwise false
@@ -147,12 +158,37 @@ public interface BlockState extends Metadatable {
boolean update(boolean force);
/**
* @return The data as a raw byte.
* Attempts to update the block represented by this state, setting it to
* the new values as defined by this state.
* <p>
* Unless force is true, this will not modify the state of a block if it
* is no longer the same type as it was when this state was taken. It will
* return false in this eventuality.
* <p>
* If force is true, it will set the type of the block to match the new
* state, set the state data and then return true.
* <p>
* If applyPhysics is true, it will trigger a physics update on
* surrounding blocks which could cause them to update or disappear.
*
* @param force true to forcefully set the state
* @param applyPhysics false to cancel updating physics on surrounding
* blocks
* @return true if the update was successful, otherwise false
*/
boolean update(boolean force, boolean applyPhysics);
/**
* @return The data as a raw byte.
* @deprecated Magic value
*/
@Deprecated
public byte getRawData();
/**
* @param data The new data value for the block.
* @deprecated Magic value
*/
@Deprecated
public void setRawData(byte data);
}

View File

@@ -6,9 +6,10 @@ import org.bukkit.inventory.Inventory;
* Represents a chest.
*/
public interface Chest extends BlockState, ContainerBlock {
/**
* Returns the chest's inventory. If this is a double chest, it returns just
* the portion of the inventory linked to this half of the chest.
* Returns the chest's inventory. If this is a double chest, it returns
* just the portion of the inventory linked to this half of the chest.
*
* @return The inventory.
*/

View File

@@ -0,0 +1,40 @@
package org.bukkit.block;
public interface CommandBlock extends BlockState {
/**
* Gets the command that this CommandBlock will run when powered.
* This will never return null. If the CommandBlock does not have a
* command, an empty String will be returned instead.
*
* @return Command that this CommandBlock will run when powered.
*/
public String getCommand();
/**
* Sets the command that this CommandBlock will run when powered.
* Setting the command to null is the same as setting it to an empty
* String.
*
* @param command Command that this CommandBlock will run when powered.
*/
public void setCommand(String command);
/**
* Gets the name of this CommandBlock. The name is used with commands
* that this CommandBlock executes. This name will never be null, and
* by default is "@".
*
* @return Name of this CommandBlock.
*/
public String getName();
/**
* Sets the name of this CommandBlock. The name is used with commands
* that this CommandBlock executes. Setting the name to null is the
* same as setting it to "@".
*
* @param name New name for this CommandBlock.
*/
public void setName(String name);
}

View File

@@ -4,6 +4,7 @@ import org.bukkit.inventory.InventoryHolder;
/**
* Indicates a block type that has inventory.
*
* @deprecated in favour of {@link InventoryHolder}
*/
@Deprecated

View File

@@ -1,14 +1,25 @@
package org.bukkit.block;
import org.bukkit.projectiles.BlockProjectileSource;
/**
* Represents a dispenser.
*/
public interface Dispenser extends BlockState, ContainerBlock {
/**
* Attempts to dispense the contents of this block<br />
* <br />
* If the block is no longer a dispenser, this will return false
* Gets the BlockProjectileSource object for this dispenser.
* <p>
* If the block is no longer a dispenser, this will return null.
*
* @return a BlockProjectileSource if valid, otherwise null
*/
public BlockProjectileSource getBlockProjectileSource();
/**
* Attempts to dispense the contents of this block.
* <p>
* If the block is no longer a dispenser, this will return false.
*
* @return true if successful, otherwise false
*/

View File

@@ -6,6 +6,9 @@ import org.bukkit.inventory.DoubleChestInventory;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
/**
* Represents a double chest.
*/
public class DoubleChest implements InventoryHolder {
private DoubleChestInventory inventory;

View File

@@ -0,0 +1,25 @@
package org.bukkit.block;
import org.bukkit.inventory.InventoryHolder;
/**
* Represents a dropper.
*/
public interface Dropper extends BlockState, InventoryHolder {
/**
* Tries to drop a randomly selected item from the Dropper's inventory,
* following the normal behavior of a Dropper.
* <p>
* Normal behavior of a Dropper is as follows:
* <p>
* If the block that the Dropper is facing is an InventoryHolder or
* ContainerBlock the randomly selected ItemStack is placed within that
* Inventory in the first slot that's available, starting with 0 and
* counting up. If the inventory is full, nothing happens.
* <p>
* If the block that the Dropper is facing is not an InventoryHolder or
* ContainerBlock, the randomly selected ItemStack is dropped on
* the ground in the form of an {@link org.bukkit.entity.Item Item}.
*/
public void drop();
}

View File

@@ -0,0 +1,10 @@
package org.bukkit.block;
import org.bukkit.inventory.InventoryHolder;
/**
* Represents a hopper.
*/
public interface Hopper extends BlockState, InventoryHolder {
}

View File

@@ -19,7 +19,9 @@ public interface NoteBlock extends BlockState {
* Gets the note.
*
* @return The note ID.
* @deprecated Magic value
*/
@Deprecated
public byte getRawNote();
/**
@@ -33,12 +35,14 @@ public interface NoteBlock extends BlockState {
* Set the note.
*
* @param note The note ID.
* @deprecated Magic value
*/
@Deprecated
public void setRawNote(byte note);
/**
* Attempts to play the note at block<br />
* <br />
* Attempts to play the note at block
* <p>
* If the block is no longer a note block, this will return false
*
* @return true if successful, otherwise false
@@ -51,7 +55,9 @@ public interface NoteBlock extends BlockState {
* @param instrument Instrument ID
* @param note Note ID
* @return true if successful, otherwise false
* @deprecated Magic value
*/
@Deprecated
public boolean play(byte instrument, byte note);
/**

View File

@@ -4,6 +4,7 @@ import java.util.HashMap;
import java.util.Map;
public enum PistonMoveReaction {
/**
* Indicates that the block can be pushed or pulled.
*/
@@ -31,7 +32,9 @@ public enum PistonMoveReaction {
/**
* @return The ID of the move reaction
* @deprecated Magic value
*/
@Deprecated
public int getId() {
return this.id;
}
@@ -39,7 +42,9 @@ public enum PistonMoveReaction {
/**
* @param id An ID
* @return The move reaction with that ID
* @deprecated Magic value
*/
@Deprecated
public static PistonMoveReaction getById(int id) {
return byId.get(id);
}

View File

@@ -14,7 +14,7 @@ public interface Sign extends BlockState {
/**
* Gets the line of text at the specified index.
* <p />
* <p>
* For example, getLine(0) will return the first line of text.
*
* @param index Line number to get the text from, starting at 0
@@ -25,7 +25,7 @@ public interface Sign extends BlockState {
/**
* Sets the line of text at the specified index.
* <p />
* <p>
* For example, setLine(0, "Line One") will set the first line of text to
* "Line One".
*

View File

@@ -0,0 +1,62 @@
package org.bukkit.block;
import org.bukkit.SkullType;
/**
* Represents a Skull
*/
public interface Skull extends BlockState {
/**
* Checks to see if the skull has an owner
*
* @return true if the skull has an owner
*/
public boolean hasOwner();
/**
* Gets the owner of the skull, if one exists
*
* @return the owner of the skull or null if the skull does not have an owner
*/
public String getOwner();
/**
* Sets the owner of the skull
* <p>
* Involves a potentially blocking web request to acquire the profile data for
* the provided name.
*
* @param name the new owner of the skull
* @return true if the owner was successfully set
*/
public boolean setOwner(String name);
/**
* Gets the rotation of the skull in the world
*
* @return the rotation of the skull
*/
public BlockFace getRotation();
/**
* Sets the rotation of the skull in the world
*
* @param rotation the rotation of the skull
*/
public void setRotation(BlockFace rotation);
/**
* Gets the type of skull
*
* @return the type of skull
*/
public SkullType getSkullType();
/**
* Sets the type of skull
*
* @param skullType the type of skull
*/
public void setSkullType(SkullType skullType);
}

View File

@@ -0,0 +1,13 @@
package org.bukkit.command;
import org.bukkit.block.Block;
public interface BlockCommandSender extends CommandSender {
/**
* Returns the block this command sender belongs to
*
* @return Block for the command sender
*/
public Block getBlock();
}

View File

@@ -1,12 +1,21 @@
package org.bukkit.command;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Server;
import org.bukkit.entity.Player;
import org.bukkit.entity.minecart.CommandMinecart;
import org.bukkit.permissions.Permissible;
import org.bukkit.plugin.PluginDescriptionFile;
import org.bukkit.util.StringUtil;
import com.google.common.collect.ImmutableList;
/**
* Represents a Command, which executes various tasks upon user input
@@ -47,6 +56,50 @@ public abstract class Command {
*/
public abstract boolean execute(CommandSender sender, String commandLabel, String[] args);
/**
* @deprecated This method is not supported and returns null
*/
@Deprecated
public List<String> tabComplete(CommandSender sender, String[] args) {
return null;
}
/**
* Executed on tab completion for this command, returning a list of
* options the player can tab through.
*
* @param sender Source object which is executing this command
* @param alias the alias being used
* @param args All arguments passed to the command, split via ' '
* @return a list of tab-completions for the specified arguments. This
* will never be null. List may be immutable.
* @throws IllegalArgumentException if sender, alias, or args is null
*/
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 0) {
return ImmutableList.of();
}
String lastWord = args[args.length - 1];
Player senderPlayer = sender instanceof Player ? (Player) sender : null;
ArrayList<String> matchedPlayers = new ArrayList<String>();
for (Player player : sender.getServer().getOnlinePlayers()) {
String name = player.getName();
if ((senderPlayer == null || senderPlayer.canSee(player)) && StringUtil.startsWithIgnoreCase(name, lastWord)) {
matchedPlayers.add(name);
}
}
Collections.sort(matchedPlayers, String.CASE_INSENSITIVE_ORDER);
return matchedPlayers;
}
/**
* Returns the name of this command
*
@@ -57,7 +110,8 @@ public abstract class Command {
}
/**
* Gets the permission required by users to be able to perform this command
* Gets the permission required by users to be able to perform this
* command
*
* @return Permission name, or null if none
*/
@@ -66,7 +120,8 @@ public abstract class Command {
}
/**
* Sets the permission required by users to be able to perform this command
* Sets the permission required by users to be able to perform this
* command
*
* @param permission Permission name or null
*/
@@ -75,9 +130,11 @@ public abstract class Command {
}
/**
* Tests the given {@link CommandSender} to see if they can perform this command.
* <p />
* If they do not have permission, they will be informed that they cannot do this.
* Tests the given {@link CommandSender} to see if they can perform this
* command.
* <p>
* If they do not have permission, they will be informed that they cannot
* do this.
*
* @param target User to test
* @return true if they can use it, otherwise false
@@ -99,8 +156,9 @@ public abstract class Command {
}
/**
* Tests the given {@link CommandSender} to see if they can perform this command.
* <p />
* Tests the given {@link CommandSender} to see if they can perform this
* command.
* <p>
* No error is sent to the sender.
*
* @param target User to test
@@ -110,7 +168,7 @@ public abstract class Command {
if ((permission == null) || (permission.length() == 0)) {
return true;
}
for (String p : permission.split(";")) {
if (target.hasPermission(p)) {
return true;
@@ -121,7 +179,7 @@ public abstract class Command {
}
/**
* Returns the current lable for this command
* Returns the current label for this command
*
* @return Label of this command or null if not registered
*/
@@ -130,12 +188,14 @@ public abstract class Command {
}
/**
* Sets the label of this command
* If the command is currently registered the label change will only take effect after
* its been reregistered e.g. after a /reload
* Sets the label of this command.
* <p>
* If the command is currently registered the label change will only take
* effect after its been re-registered e.g. after a /reload
*
* @param name The command's name
* @return returns true if the name change happened instantly or false if it was scheduled for reregistration
* @return returns true if the name change happened instantly or false if
* it was scheduled for re-registration
*/
public boolean setLabel(String name) {
this.nextLabel = name;
@@ -147,11 +207,12 @@ public abstract class Command {
}
/**
* Registers this command to a CommandMap
* Registers this command to a CommandMap.
* Once called it only allows changes the registered CommandMap
*
* @param commandMap the CommandMap to register this command to
* @return true if the registration was successful (the current registered CommandMap was the passed CommandMap or null) false otherwise
* @return true if the registration was successful (the current registered
* CommandMap was the passed CommandMap or null) false otherwise
*/
public boolean register(CommandMap commandMap) {
if (allowChangesFrom(commandMap)) {
@@ -163,10 +224,13 @@ public abstract class Command {
}
/**
* Unregisters this command from the passed CommandMap applying any outstanding changes
* Unregisters this command from the passed CommandMap applying any
* outstanding changes
*
* @param commandMap the CommandMap to unregister
* @return true if the unregistration was successfull (the current registered CommandMap was the passed CommandMap or null) false otherwise
* @return true if the unregistration was successfull (the current
* registered CommandMap was the passed CommandMap or null) false
* otherwise
*/
public boolean unregister(CommandMap commandMap) {
if (allowChangesFrom(commandMap)) {
@@ -202,7 +266,8 @@ public abstract class Command {
}
/**
* Returns a message to be displayed on a failed permission check for this command
* Returns a message to be displayed on a failed permission check for this
* command
*
* @return Permission check failed message
*/
@@ -229,10 +294,13 @@ public abstract class Command {
}
/**
* Sets the list of aliases to request on registration for this command
* Sets the list of aliases to request on registration for this command.
* This is not effective outside of defining aliases in the {@link
* PluginDescriptionFile#getCommands()} (under the
* `<code>aliases</code>' node) is equivalent to this method.
*
* @param aliases Aliases to register to this command
* @return This command object, for linking
* @param aliases aliases to register to this command
* @return this command object, for chaining
*/
public Command setAliases(List<String> aliases) {
this.aliases = aliases;
@@ -243,10 +311,12 @@ public abstract class Command {
}
/**
* Sets a brief description of this command
* Sets a brief description of this command. Defining a description in the
* {@link PluginDescriptionFile#getCommands()} (under the
* `<code>description</code>' node) is equivalent to this method.
*
* @param description New command description
* @return This command object, for linking
* @param description new command description
* @return this command object, for chaining
*/
public Command setDescription(String description) {
this.description = description;
@@ -256,8 +326,9 @@ public abstract class Command {
/**
* Sets the message sent when a permission check fails
*
* @param permissionMessage New permission message, null to indicate default message, or an empty string to indicate no message
* @return This command object, for linking
* @param permissionMessage new permission message, null to indicate
* default message, or an empty string to indicate no message
* @return this command object, for chaining
*/
public Command setPermissionMessage(String permissionMessage) {
this.permissionMessage = permissionMessage;
@@ -267,8 +338,8 @@ public abstract class Command {
/**
* Sets the example usage of this command
*
* @param usage New example usage
* @return This command object, for linking
* @param usage new example usage
* @return this command object, for chaining
*/
public Command setUsage(String usage) {
this.usageMessage = usage;
@@ -276,11 +347,32 @@ public abstract class Command {
}
public static void broadcastCommandMessage(CommandSender source, String message) {
Set<Permissible> users = Bukkit.getPluginManager().getPermissionSubscriptions(Server.BROADCAST_CHANNEL_ADMINISTRATIVE);
String result = source.getName() + ": " + message;
String colored = ChatColor.GRAY + "(" + result + ")";
broadcastCommandMessage(source, message, true);
}
if (!(source instanceof ConsoleCommandSender)) {
public static void broadcastCommandMessage(CommandSender source, String message, boolean sendToSource) {
String result = source.getName() + ": " + message;
if (source instanceof BlockCommandSender) {
BlockCommandSender blockCommandSender = (BlockCommandSender) source;
if (blockCommandSender.getBlock().getWorld().getGameRuleValue("commandBlockOutput").equalsIgnoreCase("false")) {
Bukkit.getConsoleSender().sendMessage(result);
return;
}
} else if (source instanceof CommandMinecart) {
CommandMinecart commandMinecart = (CommandMinecart) source;
if (commandMinecart.getWorld().getGameRuleValue("commandBlockOutput").equalsIgnoreCase("false")) {
Bukkit.getConsoleSender().sendMessage(result);
return;
}
}
Set<Permissible> users = Bukkit.getPluginManager().getPermissionSubscriptions(Server.BROADCAST_CHANNEL_ADMINISTRATIVE);
String colored = ChatColor.GRAY + "" + ChatColor.ITALIC + "[" + result + ChatColor.GRAY + ChatColor.ITALIC + "]";
if (sendToSource && !(source instanceof ConsoleCommandSender)) {
source.sendMessage(message);
}
@@ -296,4 +388,9 @@ public abstract class Command {
}
}
}
@Override
public String toString() {
return getClass().getName() + '(' + name + ')';
}
}

View File

@@ -7,12 +7,14 @@ package org.bukkit.command;
public class CommandException extends RuntimeException {
/**
* Creates a new instance of <code>CommandException</code> without detail message.
* Creates a new instance of <code>CommandException</code> without detail
* message.
*/
public CommandException() {}
/**
* Constructs an instance of <code>CommandException</code> with the specified detail message.
* Constructs an instance of <code>CommandException</code> with the
* specified detail message.
*
* @param msg the detail message.
*/

View File

@@ -6,37 +6,62 @@ public interface CommandMap {
/**
* Registers all the commands belonging to a certain plugin.
* <p>
* Caller can use:-
* command.getName() to determine the label registered for this command
* command.getAliases() to determine the aliases which where registered
* <ul>
* <li>command.getName() to determine the label registered for this
* command
* <li>command.getAliases() to determine the aliases which where
* registered
* </ul>
*
* @param fallbackPrefix a prefix which is prepended to each command with a ':' one or more times to make the command unique
* @param fallbackPrefix a prefix which is prepended to each command with
* a ':' one or more times to make the command unique
* @param commands a list of commands to register
*/
public void registerAll(String fallbackPrefix, List<Command> commands);
/**
* Registers a command. Returns true on success; false if name is already taken and fallback had to be used.
* Registers a command. Returns true on success; false if name is already
* taken and fallback had to be used.
* <p>
* Caller can use:-
* command.getName() to determine the label registered for this command
* command.getAliases() to determine the aliases which where registered
* <ul>
* <li>command.getName() to determine the label registered for this
* command
* <li>command.getAliases() to determine the aliases which where
* registered
* </ul>
*
* @param label the label of the command, without the '/'-prefix.
* @param fallbackPrefix a prefix which is prepended to the command with a ':' one or more times to make the command unique
* @param fallbackPrefix a prefix which is prepended to the command with a
* ':' one or more times to make the command unique
* @param command the command to register
* @return true if command was registered with the passed in label, false otherwise, which indicates the fallbackPrefix was used one or more times
* @return true if command was registered with the passed in label, false
* otherwise, which indicates the fallbackPrefix was used one or more
* times
*/
public boolean register(String label, String fallbackPrefix, Command command);
/**
* Registers a command. Returns true on success; false if name is already taken and fallback had to be used.
* Registers a command. Returns true on success; false if name is already
* taken and fallback had to be used.
* <p>
* Caller can use:-
* command.getName() to determine the label registered for this command
* command.getAliases() to determine the aliases which where registered
* <ul>
* <li>command.getName() to determine the label registered for this
* command
* <li>command.getAliases() to determine the aliases which where
* registered
* </ul>
*
* @param fallbackPrefix a prefix which is prepended to the command with a ':' one or more times to make the command unique
* @param command the command to register, from which label is determined from the command name
* @return true if command was registered with the passed in label, false otherwise, which indicates the fallbackPrefix was used one or more times
* @param fallbackPrefix a prefix which is prepended to the command with a
* ':' one or more times to make the command unique
* @param command the command to register, from which label is determined
* from the command name
* @return true if command was registered with the passed in label, false
* otherwise, which indicates the fallbackPrefix was used one or more
* times
*/
public boolean register(String fallbackPrefix, Command command);
@@ -46,7 +71,8 @@ public interface CommandMap {
* @param sender The command's sender
* @param cmdLine command + arguments. Example: "/test abc 123"
* @return returns false if no target is found, true otherwise.
* @throws CommandException Thrown when the executor for the given command fails with an unhandled exception
* @throws CommandException Thrown when the executor for the given command
* fails with an unhandled exception
*/
public boolean dispatch(CommandSender sender, String cmdLine) throws CommandException;
@@ -59,7 +85,25 @@ public interface CommandMap {
* Gets the command registered to the specified name
*
* @param name Name of the command to retrieve
* @return Command with the specified name or null if a command with that label doesn't exist
* @return Command with the specified name or null if a command with that
* label doesn't exist
*/
public Command getCommand(String name);
/**
* Looks for the requested command and executes an appropriate
* tab-completer if found. This method will also tab-complete partial
* commands.
*
* @param sender The command's sender.
* @param cmdLine The entire command string to tab-complete, excluding
* initial slash.
* @return a list of possible tab-completions. This list may be immutable.
* Will be null if no matching command of which sender has permission.
* @throws CommandException Thrown when the tab-completer for the given
* command fails with an unhandled exception
* @throws IllegalArgumentException if either sender or cmdLine are null
*/
public List<String> tabComplete(CommandSender sender, String cmdLine) throws IllegalArgumentException;
}

View File

@@ -0,0 +1,124 @@
package org.bukkit.command;
import java.util.ArrayList;
import java.util.logging.Level;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.server.RemoteServerCommandEvent;
import org.bukkit.event.server.ServerCommandEvent;
public class FormattedCommandAlias extends Command {
private final String[] formatStrings;
public FormattedCommandAlias(String alias, String[] formatStrings) {
super(alias);
this.formatStrings = formatStrings;
}
@Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
boolean result = false;
ArrayList<String> commands = new ArrayList<String>();
for (String formatString : formatStrings) {
try {
commands.add(buildCommand(formatString, args));
} catch (Throwable throwable) {
if (throwable instanceof IllegalArgumentException) {
sender.sendMessage(throwable.getMessage());
} else {
sender.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command");
}
return false;
}
}
for (String command : commands) {
result |= Bukkit.dispatchCommand(sender, command);
}
return result;
}
private String buildCommand(String formatString, String[] args) {
int index = formatString.indexOf("$");
while (index != -1) {
int start = index;
if (index > 0 && formatString.charAt(start - 1) == '\\') {
formatString = formatString.substring(0, start - 1) + formatString.substring(start);
index = formatString.indexOf("$", index);
continue;
}
boolean required = false;
if (formatString.charAt(index + 1) == '$') {
required = true;
// Move index past the second $
index++;
}
// Move index past the $
index++;
int argStart = index;
while (index < formatString.length() && inRange(((int) formatString.charAt(index)) - 48, 0, 9)) {
// Move index past current digit
index++;
}
// No numbers found
if (argStart == index) {
throw new IllegalArgumentException("Invalid replacement token");
}
int position = Integer.valueOf(formatString.substring(argStart, index));
// Arguments are not 0 indexed
if (position == 0) {
throw new IllegalArgumentException("Invalid replacement token");
}
// Convert position to 0 index
position--;
boolean rest = false;
if (index < formatString.length() && formatString.charAt(index) == '-') {
rest = true;
// Move index past the -
index++;
}
int end = index;
if (required && position >= args.length) {
throw new IllegalArgumentException("Missing required argument " + (position + 1));
}
StringBuilder replacement = new StringBuilder();
if (rest && position < args.length) {
for (int i = position; i < args.length; i++) {
if (i != position) {
replacement.append(' ');
}
replacement.append(args[i]);
}
} else if (position < args.length) {
replacement.append(args[position]);
}
formatString = formatString.substring(0, start) + replacement.toString() + formatString.substring(end);
// Move index past the replaced data so we don't process it again
index = start + replacement.length();
// Move to the next replacement token
index = formatString.indexOf("$", index);
}
return formatString;
}
private static boolean inRange(int i, int j, int k) {
return i >= j && i <= k;
}
}

View File

@@ -10,7 +10,12 @@ public class MultipleCommandAlias extends Command {
super(name);
this.commands = commands;
}
/**
* Gets the commands associated with the multi-command alias.
*
* @return commands associated with alias
*/
public Command[] getCommands() {
return commands;
}

View File

@@ -1,5 +1,8 @@
package org.bukkit.command;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.bukkit.plugin.Plugin;
/**
@@ -8,6 +11,7 @@ import org.bukkit.plugin.Plugin;
public final class PluginCommand extends Command implements PluginIdentifiableCommand {
private final Plugin owningPlugin;
private CommandExecutor executor;
private TabCompleter completer;
protected PluginCommand(String name, Plugin owner) {
super(name);
@@ -57,7 +61,7 @@ public final class PluginCommand extends Command implements PluginIdentifiableCo
* @param executor New executor to run
*/
public void setExecutor(CommandExecutor executor) {
this.executor = executor;
this.executor = executor == null ? owningPlugin : executor;
}
/**
@@ -69,6 +73,27 @@ public final class PluginCommand extends Command implements PluginIdentifiableCo
return executor;
}
/**
* Sets the {@link TabCompleter} to run when tab-completing this command.
* <p>
* If no TabCompleter is specified, and the command's executor implements
* TabCompleter, then the executor will be used for tab completion.
*
* @param completer New tab completer
*/
public void setTabCompleter(TabCompleter completer) {
this.completer = completer;
}
/**
* Gets the {@link TabCompleter} associated with this command.
*
* @return TabCompleter object linked to this command
*/
public TabCompleter getTabCompleter() {
return completer;
}
/**
* Gets the owner of this PluginCommand
*
@@ -77,4 +102,59 @@ public final class PluginCommand extends Command implements PluginIdentifiableCo
public Plugin getPlugin() {
return owningPlugin;
}
/**
* {@inheritDoc}
* <p>
* Delegates to the tab completer if present.
* <p>
* If it is not present or returns null, will delegate to the current
* command executor if it implements {@link TabCompleter}. If a non-null
* list has not been found, will default to standard player name
* completion in {@link
* Command#tabComplete(CommandSender, String, String[])}.
* <p>
* This method does not consider permissions.
*
* @throws CommandException if the completer or executor throw an
* exception during the process of tab-completing.
* @throws IllegalArgumentException if sender, alias, or args is null
*/
@Override
public java.util.List<String> tabComplete(CommandSender sender, String alias, String[] args) throws CommandException, IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
List<String> completions = null;
try {
if (completer != null) {
completions = completer.onTabComplete(sender, this, alias, args);
}
if (completions == null && executor instanceof TabCompleter) {
completions = ((TabCompleter) executor).onTabComplete(sender, this, alias, args);
}
} catch (Throwable ex) {
StringBuilder message = new StringBuilder();
message.append("Unhandled exception during tab completion for command '/").append(alias).append(' ');
for (String arg : args) {
message.append(arg).append(' ');
}
message.deleteCharAt(message.length() - 1).append("' in plugin ").append(owningPlugin.getDescription().getFullName());
throw new CommandException(message.toString(), ex);
}
if (completions == null) {
return super.tabComplete(sender, alias, args);
}
return completions;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder(super.toString());
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
stringBuilder.append(", ").append(owningPlugin.getDescription().getFullName()).append(')');
return stringBuilder.toString();
}
}

View File

@@ -5,6 +5,7 @@ import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
public class PluginCommandYamlParser {
@@ -19,6 +20,10 @@ public class PluginCommandYamlParser {
}
for (Entry<String, Map<String, Object>> entry : map.entrySet()) {
if (entry.getKey().contains(":")) {
Bukkit.getServer().getLogger().severe("Could not load command " + entry.getKey() + " for plugin " + plugin.getName() + ": Illegal Characters");
continue;
}
Command newCmd = new PluginCommand(entry.getKey(), plugin);
Object description = entry.getValue().get("description");
Object usage = entry.getValue().get("usage");
@@ -39,10 +44,18 @@ public class PluginCommandYamlParser {
if (aliases instanceof List) {
for (Object o : (List<?>) aliases) {
if (o.toString().contains(":")) {
Bukkit.getServer().getLogger().severe("Could not load alias " + o.toString() + " for plugin " + plugin.getName() + ": Illegal Characters");
continue;
}
aliasList.add(o.toString());
}
} else {
aliasList.add(aliases.toString());
if (aliases.toString().contains(":")) {
Bukkit.getServer().getLogger().severe("Could not load alias " + aliases.toString() + " for plugin " + plugin.getName() + ": Illegal Characters");
} else {
aliasList.add(aliases.toString());
}
}
newCmd.setAliases(aliasList);

View File

@@ -3,12 +3,13 @@ package org.bukkit.command;
import org.bukkit.plugin.Plugin;
/**
* This interface is used by the help system to group commands into sub-indexes based
* on the {@link Plugin} they are a part of. Custom command implementations will need to
* implement this interface to have a sub-index automatically generated on the plugin's
* behalf.
* This interface is used by the help system to group commands into
* sub-indexes based on the {@link Plugin} they are a part of. Custom command
* implementations will need to implement this interface to have a sub-index
* automatically generated on the plugin's behalf.
*/
public interface PluginIdentifiableCommand {
/**
* Gets the owner of this PluginIdentifiableCommand.
*

View File

@@ -1,58 +1,83 @@
package org.bukkit.command;
import org.bukkit.command.defaults.*;
import java.util.*;
import org.bukkit.Server;
import static org.bukkit.util.Java15Compat.Arrays_copyOfRange;
public class SimpleCommandMap implements CommandMap {
protected final Map<String, Command> knownCommands = new HashMap<String, Command>();
protected final Set<String> aliases = new HashSet<String>();
private final Server server;
protected static final Set<VanillaCommand> fallbackCommands = new HashSet<VanillaCommand>();
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
static {
fallbackCommands.add(new ListCommand());
fallbackCommands.add(new StopCommand());
fallbackCommands.add(new SaveCommand());
fallbackCommands.add(new SaveOnCommand());
fallbackCommands.add(new SaveOffCommand());
fallbackCommands.add(new OpCommand());
fallbackCommands.add(new DeopCommand());
fallbackCommands.add(new BanIpCommand());
fallbackCommands.add(new PardonIpCommand());
fallbackCommands.add(new BanCommand());
fallbackCommands.add(new PardonCommand());
fallbackCommands.add(new KickCommand());
fallbackCommands.add(new TeleportCommand());
fallbackCommands.add(new GiveCommand());
fallbackCommands.add(new TimeCommand());
fallbackCommands.add(new SayCommand());
fallbackCommands.add(new WhitelistCommand());
fallbackCommands.add(new TellCommand());
fallbackCommands.add(new MeCommand());
fallbackCommands.add(new KillCommand());
fallbackCommands.add(new GameModeCommand());
fallbackCommands.add(new HelpCommand());
fallbackCommands.add(new ExpCommand());
fallbackCommands.add(new ToggleDownfallCommand());
fallbackCommands.add(new BanListCommand());
}
import org.apache.commons.lang.Validate;
import org.bukkit.Server;
import org.bukkit.command.defaults.*;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
public class SimpleCommandMap implements CommandMap {
private static final Pattern PATTERN_ON_SPACE = Pattern.compile(" ", Pattern.LITERAL);
protected final Map<String, Command> knownCommands = new HashMap<String, Command>();
private final Server server;
public SimpleCommandMap(final Server server) {
this.server = server;
setDefaultCommands(server);
setDefaultCommands();
}
private void setDefaultCommands(final Server server) {
private void setDefaultCommands() {
register("bukkit", new SaveCommand());
register("bukkit", new SaveOnCommand());
register("bukkit", new SaveOffCommand());
register("bukkit", new StopCommand());
register("bukkit", new VersionCommand("version"));
register("bukkit", new ReloadCommand("reload"));
register("bukkit", new PluginsCommand("plugins"));
register("bukkit", new TimingsCommand("timings"));
}
public void setFallbackCommands() {
register("bukkit", new ListCommand());
register("bukkit", new OpCommand());
register("bukkit", new DeopCommand());
register("bukkit", new BanIpCommand());
register("bukkit", new PardonIpCommand());
register("bukkit", new BanCommand());
register("bukkit", new PardonCommand());
register("bukkit", new KickCommand());
register("bukkit", new TeleportCommand());
register("bukkit", new GiveCommand());
register("bukkit", new TimeCommand());
register("bukkit", new SayCommand());
register("bukkit", new WhitelistCommand());
register("bukkit", new TellCommand());
register("bukkit", new MeCommand());
register("bukkit", new KillCommand());
register("bukkit", new GameModeCommand());
register("bukkit", new HelpCommand());
register("bukkit", new ExpCommand());
register("bukkit", new ToggleDownfallCommand());
register("bukkit", new BanListCommand());
register("bukkit", new DefaultGameModeCommand());
register("bukkit", new SeedCommand());
register("bukkit", new DifficultyCommand());
register("bukkit", new WeatherCommand());
register("bukkit", new SpawnpointCommand());
register("bukkit", new ClearCommand());
register("bukkit", new GameRuleCommand());
register("bukkit", new EnchantCommand());
register("bukkit", new TestForCommand());
register("bukkit", new EffectCommand());
register("bukkit", new ScoreboardCommand());
register("bukkit", new PlaySoundCommand());
register("bukkit", new SpreadPlayersCommand());
register("bukkit", new SetWorldSpawnCommand());
register("bukkit", new SetIdleTimeoutCommand());
register("bukkit", new AchievementCommand());
}
/**
* {@inheritDoc}
*/
@@ -75,80 +100,69 @@ public class SimpleCommandMap implements CommandMap {
* {@inheritDoc}
*/
public boolean register(String label, String fallbackPrefix, Command command) {
boolean registeredPassedLabel = register(label, fallbackPrefix, command, false);
label = label.toLowerCase().trim();
fallbackPrefix = fallbackPrefix.toLowerCase().trim();
boolean registered = register(label, command, false, fallbackPrefix);
Iterator<String> iterator = command.getAliases().iterator();
while (iterator.hasNext()) {
if (!register((String) iterator.next(), fallbackPrefix, command, true)) {
if (!register(iterator.next(), command, true, fallbackPrefix)) {
iterator.remove();
}
}
// If we failed to register under the real name, we need to set the command label to the direct address
if (!registered) {
command.setLabel(fallbackPrefix + ":" + label);
}
// Register to us so further updates of the commands label and aliases are postponed until its reregistered
command.register(this);
return registeredPassedLabel;
return registered;
}
/**
* Registers a command with the given name is possible, otherwise uses fallbackPrefix to create a unique name if its not an alias
* Registers a command with the given name is possible. Also uses
* fallbackPrefix to create a unique name.
*
* @param label the name of the command, without the '/'-prefix.
* @param fallbackPrefix a prefix which is prepended to the command with a ':' one or more times to make the command unique
* @param command the command to register
* @return true if command was registered with the passed in label, false otherwise.
* If isAlias was true a return of false indicates no command was registerd
* If isAlias was false a return of false indicates the fallbackPrefix was used one or more times to create a unique name for the command
* @param isAlias whether the command is an alias
* @param fallbackPrefix a prefix which is prepended to the command for a
* unique address
* @return true if command was registered, false otherwise.
*/
private synchronized boolean register(String label, String fallbackPrefix, Command command, boolean isAlias) {
String lowerLabel = label.trim().toLowerCase();
if (isAlias && knownCommands.containsKey(lowerLabel)) {
// Request is for an alias and it conflicts with a existing command or previous alias ignore it
private synchronized boolean register(String label, Command command, boolean isAlias, String fallbackPrefix) {
knownCommands.put(fallbackPrefix + ":" + label, command);
if ((command instanceof VanillaCommand || isAlias) && knownCommands.containsKey(label)) {
// Request is for an alias/fallback command and it conflicts with
// a existing command or previous alias ignore it
// Note: This will mean it gets removed from the commands list of active aliases
return false;
}
String lowerPrefix = fallbackPrefix.trim().toLowerCase();
boolean registerdPassedLabel = true;
boolean registered = true;
// If the command exists but is an alias we overwrite it, otherwise we rename it based on the fallbackPrefix
while (knownCommands.containsKey(lowerLabel) && !aliases.contains(lowerLabel)) {
lowerLabel = lowerPrefix + ":" + lowerLabel;
registerdPassedLabel = false;
// If the command exists but is an alias we overwrite it, otherwise we return
Command conflict = knownCommands.get(label);
if (conflict != null && conflict.getLabel().equals(label)) {
return false;
}
if (isAlias) {
aliases.add(lowerLabel);
} else {
// Ensure lowerLabel isn't listed as a alias anymore and update the commands registered name
aliases.remove(lowerLabel);
command.setLabel(lowerLabel);
if (!isAlias) {
command.setLabel(label);
}
knownCommands.put(lowerLabel, command);
knownCommands.put(label, command);
return registerdPassedLabel;
}
protected Command getFallback(String label) {
for (VanillaCommand cmd : fallbackCommands) {
if (cmd.matches(label)) {
return cmd;
}
}
return null;
}
public Set<VanillaCommand> getFallbackCommands() {
return Collections.unmodifiableSet(fallbackCommands);
return registered;
}
/**
* {@inheritDoc}
*/
public boolean dispatch(CommandSender sender, String commandLine) throws CommandException {
String[] args = commandLine.split(" ");
String[] args = PATTERN_ON_SPACE.split(commandLine);
if (args.length == 0) {
return false;
@@ -179,53 +193,108 @@ public class SimpleCommandMap implements CommandMap {
entry.getValue().unregister(this);
}
knownCommands.clear();
aliases.clear();
setDefaultCommands(server);
setDefaultCommands();
}
public Command getCommand(String name) {
Command target = knownCommands.get(name.toLowerCase());
if (target == null) {
target = getFallback(name);
}
Command target = knownCommands.get(name.toLowerCase());
return target;
}
public List<String> tabComplete(CommandSender sender, String cmdLine) {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(cmdLine, "Command line cannot null");
int spaceIndex = cmdLine.indexOf(' ');
if (spaceIndex == -1) {
ArrayList<String> completions = new ArrayList<String>();
Map<String, Command> knownCommands = this.knownCommands;
final String prefix = (sender instanceof Player ? "/" : "");
for (Map.Entry<String, Command> commandEntry : knownCommands.entrySet()) {
Command command = commandEntry.getValue();
if (!command.testPermissionSilent(sender)) {
continue;
}
String name = commandEntry.getKey(); // Use the alias, not command name
if (StringUtil.startsWithIgnoreCase(name, cmdLine)) {
completions.add(prefix + name);
}
}
Collections.sort(completions, String.CASE_INSENSITIVE_ORDER);
return completions;
}
String commandName = cmdLine.substring(0, spaceIndex);
Command target = getCommand(commandName);
if (target == null) {
return null;
}
if (!target.testPermissionSilent(sender)) {
return null;
}
String argLine = cmdLine.substring(spaceIndex + 1, cmdLine.length());
String[] args = PATTERN_ON_SPACE.split(argLine, -1);
try {
return target.tabComplete(sender, commandName, args);
} catch (CommandException ex) {
throw ex;
} catch (Throwable ex) {
throw new CommandException("Unhandled exception executing tab-completer for '" + cmdLine + "' in " + target, ex);
}
}
public Collection<Command> getCommands() {
return knownCommands.values();
return Collections.unmodifiableCollection(knownCommands.values());
}
public void registerServerAliases() {
Map<String, String[]> values = server.getCommandAliases();
for (String alias : values.keySet()) {
String[] targetNames = values.get(alias);
List<Command> targets = new ArrayList<Command>();
if (alias.contains(":") || alias.contains(" ")) {
server.getLogger().warning("Could not register alias " + alias + " because it contains illegal characters");
continue;
}
String[] commandStrings = values.get(alias);
List<String> targets = new ArrayList<String>();
StringBuilder bad = new StringBuilder();
for (String name : targetNames) {
Command command = getCommand(name);
for (String commandString : commandStrings) {
String[] commandArgs = commandString.split(" ");
Command command = getCommand(commandArgs[0]);
if (command == null) {
if (bad.length() > 0) {
bad.append(", ");
}
bad.append(name);
bad.append(commandString);
} else {
targets.add(command);
targets.add(commandString);
}
}
// We register these as commands so they have absolute priority.
if (targets.size() > 0) {
knownCommands.put(alias.toLowerCase(), new MultipleCommandAlias(alias.toLowerCase(), targets.toArray(new Command[0])));
} else {
knownCommands.remove(alias.toLowerCase());
if (bad.length() > 0) {
server.getLogger().warning("Could not register alias " + alias + " because it contains commands that do not exist: " + bad);
continue;
}
if (bad.length() > 0) {
server.getLogger().warning("The following command(s) could not be aliased under '" + alias + "' because they do not exist: " + bad);
// We register these as commands so they have absolute priority.
if (targets.size() > 0) {
knownCommands.put(alias.toLowerCase(), new FormattedCommandAlias(alias.toLowerCase(), targets.toArray(new String[targets.size()])));
} else {
knownCommands.remove(alias.toLowerCase());
}
}
}

View File

@@ -0,0 +1,16 @@
package org.bukkit.command;
import java.util.List;
/**
* Represents a class which can handle command tab completion and commands
*
* @deprecated Remains for plugins that would have implemented it even without
* functionality
* @see TabExecutor
*/
@Deprecated
public interface TabCommandExecutor extends CommandExecutor {
public List<String> onTabComplete();
}

View File

@@ -0,0 +1,22 @@
package org.bukkit.command;
import java.util.List;
/**
* Represents a class which can suggest tab completions for commands.
*/
public interface TabCompleter {
/**
* Requests a list of possible completions for a command argument.
*
* @param sender Source of the command
* @param command Command which was executed
* @param alias The alias used
* @param args The arguments passed to the command, including final
* partial argument to be completed and command label
* @return A List of possible completions for the final argument, or null
* to default to the command executor
*/
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args);
}

View File

@@ -0,0 +1,8 @@
package org.bukkit.command;
/**
* This class is provided as a convenience to implement both TabCompleter and
* CommandExecutor.
*/
public interface TabExecutor extends TabCompleter, CommandExecutor {
}

View File

@@ -0,0 +1,187 @@
package org.bukkit.command.defaults;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.bukkit.Achievement;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Statistic;
import org.bukkit.Material;
import org.bukkit.Statistic.Type;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerAchievementAwardedEvent;
import org.bukkit.event.player.PlayerStatisticIncrementEvent;
import com.google.common.collect.ImmutableList;
public class AchievementCommand extends VanillaCommand {
public AchievementCommand() {
super("achievement");
this.description = "Gives the specified player an achievement or changes a statistic value. Use '*' to give all achievements.";
this.usageMessage = "/achievement give <stat_name> [player]";
this.setPermission("bukkit.command.achievement");
}
@Override
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) return true;
if (args.length < 2) {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
if (!args[0].equalsIgnoreCase("give")) {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
String statisticString = args[1];
Player player = null;
if (args.length > 2) {
player = Bukkit.getPlayer(args[1]);
} else if (sender instanceof Player) {
player = (Player) sender;
}
if (player == null) {
sender.sendMessage("You must specify which player you wish to perform this action on.");
return true;
}
if (statisticString.equals("*")) {
for (Achievement achievement : Achievement.values()) {
if (player.hasAchievement(achievement)) {
continue;
}
PlayerAchievementAwardedEvent event = new PlayerAchievementAwardedEvent(player, achievement);
Bukkit.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
player.awardAchievement(achievement);
}
}
Command.broadcastCommandMessage(sender, String.format("Successfully given all achievements to %s", player.getName()));
return true;
}
Achievement achievement = Bukkit.getUnsafe().getAchievementFromInternalName(statisticString);
Statistic statistic = Bukkit.getUnsafe().getStatisticFromInternalName(statisticString);
if (achievement != null) {
if (player.hasAchievement(achievement)) {
sender.sendMessage(String.format("%s already has achievement %s", player.getName(), statisticString));
return true;
}
PlayerAchievementAwardedEvent event = new PlayerAchievementAwardedEvent(player, achievement);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
sender.sendMessage(String.format("Unable to award %s the achievement %s", player.getName(), statisticString));
return true;
}
player.awardAchievement(achievement);
Command.broadcastCommandMessage(sender, String.format("Successfully given %s the stat %s", player.getName(), statisticString));
return true;
}
if (statistic == null) {
sender.sendMessage(String.format("Unknown achievement or statistic '%s'", statisticString));
return true;
}
if (statistic.getType() == Type.UNTYPED) {
PlayerStatisticIncrementEvent event = new PlayerStatisticIncrementEvent(player, statistic, player.getStatistic(statistic), player.getStatistic(statistic) + 1);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
sender.sendMessage(String.format("Unable to increment %s for %s", statisticString, player.getName()));
return true;
}
player.incrementStatistic(statistic);
Command.broadcastCommandMessage(sender, String.format("Successfully given %s the stat %s", player.getName(), statisticString));
return true;
}
if (statistic.getType() == Type.ENTITY) {
EntityType entityType = EntityType.fromName(statisticString.substring(statisticString.lastIndexOf(".") + 1));
if (entityType == null) {
sender.sendMessage(String.format("Unknown achievement or statistic '%s'", statisticString));
return true;
}
PlayerStatisticIncrementEvent event = new PlayerStatisticIncrementEvent(player, statistic, player.getStatistic(statistic), player.getStatistic(statistic) + 1, entityType);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
sender.sendMessage(String.format("Unable to increment %s for %s", statisticString, player.getName()));
return true;
}
try {
player.incrementStatistic(statistic, entityType);
} catch (IllegalArgumentException e) {
sender.sendMessage(String.format("Unknown achievement or statistic '%s'", statisticString));
return true;
}
} else {
int id;
try {
id = getInteger(sender, statisticString.substring(statisticString.lastIndexOf(".") + 1), 0, Integer.MAX_VALUE, true);
} catch (NumberFormatException e) {
sender.sendMessage(e.getMessage());
return true;
}
Material material = Material.getMaterial(id);
if (material == null) {
sender.sendMessage(String.format("Unknown achievement or statistic '%s'", statisticString));
return true;
}
PlayerStatisticIncrementEvent event = new PlayerStatisticIncrementEvent(player, statistic, player.getStatistic(statistic), player.getStatistic(statistic) + 1, material);
Bukkit.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
sender.sendMessage(String.format("Unable to increment %s for %s", statisticString, player.getName()));
return true;
}
try {
player.incrementStatistic(statistic, material);
} catch (IllegalArgumentException e) {
sender.sendMessage(String.format("Unknown achievement or statistic '%s'", statisticString));
return true;
}
}
Command.broadcastCommandMessage(sender, String.format("Successfully given %s the stat %s", player.getName(), statisticString));
return true;
}
@Override
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 1) {
return Arrays.asList("give");
}
if (args.length == 2) {
return Bukkit.getUnsafe().tabCompleteInternalStatisticOrAchievementName(args[1], new ArrayList<String>());
}
if (args.length == 3) {
return super.tabComplete(sender, alias, args);
}
return ImmutableList.of();
}
}

View File

@@ -1,35 +1,55 @@
package org.bukkit.command.defaults;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.bukkit.BanList;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.google.common.collect.ImmutableList;
public class BanCommand extends VanillaCommand {
public BanCommand() {
super("ban");
this.description = "Prevents the specified player from using this server";
this.usageMessage = "/ban <player>";
this.usageMessage = "/ban <player> [reason ...]";
this.setPermission("bukkit.command.ban.player");
}
@Override
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) return true;
if (args.length != 1) {
if (args.length == 0) {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
Bukkit.getOfflinePlayer(args[0]).setBanned(true);
if (Bukkit.getPlayer(args[0]) != null) Bukkit.getPlayer(args[0]).kickPlayer("Banned by admin.");
Command.broadcastCommandMessage(sender, "Banning " + args[0]);
String reason = args.length > 0 ? StringUtils.join(args, ' ', 1, args.length) : null;
Bukkit.getBanList(BanList.Type.NAME).addBan(args[0], reason, null, sender.getName());
Player player = Bukkit.getPlayer(args[0]);
if (player != null) {
player.kickPlayer("Banned by admin.");
}
Command.broadcastCommandMessage(sender, "Banned player " + args[0]);
return true;
}
@Override
public boolean matches(String input) {
return input.equalsIgnoreCase("ban");
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length >= 1) {
return super.tabComplete(sender, alias, args);
}
return ImmutableList.of();
}
}

View File

@@ -1,34 +1,77 @@
package org.bukkit.command.defaults;
import java.util.List;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.bukkit.BanList;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.google.common.collect.ImmutableList;
public class BanIpCommand extends VanillaCommand {
public static final Pattern ipValidity = Pattern.compile("^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\.([01]?\\d\\d?|2[0-4]\\d|25[0-5])$");
public BanIpCommand() {
super("ban-ip");
this.description = "Prevents the specified IP address from using this server";
this.usageMessage = "/ban-ip <address>";
this.usageMessage = "/ban-ip <address|player> [reason ...]";
this.setPermission("bukkit.command.ban.ip");
}
@Override
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) return true;
if (args.length != 1) {
if (args.length < 1) {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
Bukkit.banIP(args[0]);
Command.broadcastCommandMessage(sender, "Banning ip " + args[0]);
String reason = args.length > 0 ? StringUtils.join(args, ' ', 1, args.length) : null;
if (ipValidity.matcher(args[0]).matches()) {
processIPBan(args[0], sender, reason);
} else {
Player player = Bukkit.getPlayer(args[0]);
if (player == null) {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
processIPBan(player.getAddress().getAddress().getHostAddress(), sender, reason);
}
return true;
}
private void processIPBan(String ip, CommandSender sender, String reason) {
Bukkit.getBanList(BanList.Type.IP).addBan(ip, reason, null, sender.getName());
// Find all matching players and kick
for (Player player : Bukkit.getOnlinePlayers()) {
if (player.getAddress().getAddress().getHostAddress().equals(ip)) {
player.kickPlayer("You have been IP banned.");
}
}
Command.broadcastCommandMessage(sender, "Banned IP Address " + ip);
}
@Override
public boolean matches(String input) {
return input.equalsIgnoreCase("ban-ip");
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 1) {
return super.tabComplete(sender, alias, args);
}
return ImmutableList.of();
}
}

View File

@@ -1,15 +1,27 @@
package org.bukkit.command.defaults;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.apache.commons.lang.Validate;
import org.bukkit.BanEntry;
import org.bukkit.BanList;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.util.StringUtil;
import com.google.common.collect.ImmutableList;
public class BanListCommand extends VanillaCommand {
private static final List<String> BANLIST_TYPES = ImmutableList.of("ips", "players");
public BanListCommand() {
super("banlist");
this.description = "View all players banned from this server";
this.usageMessage = "/banlist";
this.usageMessage = "/banlist [ips|players]";
this.setPermission("bukkit.command.ban.list");
}
@@ -17,21 +29,45 @@ public class BanListCommand extends VanillaCommand {
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) return true;
StringBuilder message = new StringBuilder().append(ChatColor.GRAY).append("Ban list: ");
int count = 0;
for (OfflinePlayer p : Bukkit.getServer().getBannedPlayers()) {
if (count++ > 0) {
message.append(", ");
BanList.Type banType = BanList.Type.NAME;
if (args.length > 0) {
if (args[0].equalsIgnoreCase("ips")) {
banType = BanList.Type.IP;
} else if (!args[0].equalsIgnoreCase("players")) {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
message.append(p.getName());
}
StringBuilder message = new StringBuilder();
BanEntry[] banlist = Bukkit.getBanList(banType).getBanEntries().toArray(new BanEntry[0]);
for (int x = 0; x < banlist.length; x++) {
if (x != 0) {
if (x == banlist.length - 1) {
message.append(" and ");
} else {
message.append(", ");
}
}
message.append(banlist[x].getTarget());
}
sender.sendMessage("There are " + banlist.length + " total banned players:");
sender.sendMessage(message.toString());
return true;
}
@Override
public boolean matches(String input) {
return input.equalsIgnoreCase("banlist");
public List<String> tabComplete(CommandSender sender, String alias, String[] args) {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 1) {
return StringUtil.copyPartialMatches(args[0], BANLIST_TYPES, new ArrayList<String>(BANLIST_TYPES.size()));
}
return ImmutableList.of();
}
}

View File

@@ -1,10 +1,10 @@
package org.bukkit.command.defaults;
import org.bukkit.command.Command;
import java.util.List;
public abstract class BukkitCommand extends Command{
import org.bukkit.command.Command;
public abstract class BukkitCommand extends Command {
protected BukkitCommand(String name) {
super(name);
}

View File

@@ -0,0 +1,114 @@
package org.bukkit.command.defaults;
import com.google.common.collect.ImmutableList;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ClearCommand extends VanillaCommand {
private static List<String> materials;
static {
ArrayList<String> materialList = new ArrayList<String>();
for (Material material : Material.values()) {
materialList.add(material.name());
}
Collections.sort(materialList);
materials = ImmutableList.copyOf(materialList);
}
public ClearCommand() {
super("clear");
this.description = "Clears the player's inventory. Can specify item and data filters too.";
this.usageMessage = "/clear <player> [item] [data]";
this.setPermission("bukkit.command.clear");
}
@Override
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) return true;
Player player = null;
if (args.length > 0) {
player = Bukkit.getPlayer(args[0]);
} else if (sender instanceof Player) {
player = (Player) sender;
}
if (player != null) {
int id;
if (args.length > 1 && !(args[1].equals("-1"))) {
Material material = Material.matchMaterial(args[1]);
if (material == null) {
sender.sendMessage(ChatColor.RED + "There's no item called " + args[1]);
return false;
}
id = material.getId();
} else {
id = -1;
}
int data = args.length >= 3 ? getInteger(sender, args[2], 0) : -1;
int count = player.getInventory().clear(id, data);
Command.broadcastCommandMessage(sender, "Cleared the inventory of " + player.getDisplayName() + ", removing " + count + " items");
} else if (args.length == 0) {
sender.sendMessage(ChatColor.RED + "Please provide a player!");
} else {
sender.sendMessage(ChatColor.RED + "Can't find player " + args[0]);
}
return true;
}
@Override
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 1) {
return super.tabComplete(sender, alias, args);
}
if (args.length == 2) {
final String arg = args[1];
final List<String> materials = ClearCommand.materials;
List<String> completion = null;
final int size = materials.size();
int i = Collections.binarySearch(materials, arg, String.CASE_INSENSITIVE_ORDER);
if (i < 0) {
// Insertion (start) index
i = -1 - i;
}
for ( ; i < size; i++) {
String material = materials.get(i);
if (StringUtil.startsWithIgnoreCase(material, arg)) {
if (completion == null) {
completion = new ArrayList<String>();
}
completion.add(material);
} else {
break;
}
}
if (completion != null) {
return completion;
}
}
return ImmutableList.of();
}
}

View File

@@ -0,0 +1,70 @@
package org.bukkit.command.defaults;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.util.StringUtil;
import com.google.common.collect.ImmutableList;
public class DefaultGameModeCommand extends VanillaCommand {
private static final List<String> GAMEMODE_NAMES = ImmutableList.of("adventure", "creative", "survival");
public DefaultGameModeCommand() {
super("defaultgamemode");
this.description = "Set the default gamemode";
this.usageMessage = "/defaultgamemode <mode>";
this.setPermission("bukkit.command.defaultgamemode");
}
@Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
if (!testPermission(sender)) return true;
if (args.length == 0) {
sender.sendMessage("Usage: " + usageMessage);
return false;
}
String modeArg = args[0];
int value = -1;
try {
value = Integer.parseInt(modeArg);
} catch (NumberFormatException ex) {}
GameMode mode = GameMode.getByValue(value);
if (mode == null) {
if (modeArg.equalsIgnoreCase("creative") || modeArg.equalsIgnoreCase("c")) {
mode = GameMode.CREATIVE;
} else if (modeArg.equalsIgnoreCase("adventure") || modeArg.equalsIgnoreCase("a")) {
mode = GameMode.ADVENTURE;
} else {
mode = GameMode.SURVIVAL;
}
}
Bukkit.getServer().setDefaultGameMode(mode);
Command.broadcastCommandMessage(sender, "Default game mode set to " + mode.toString().toLowerCase());
return true;
}
@Override
public List<String> tabComplete(CommandSender sender, String alias, String[] args) {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 1) {
return StringUtil.copyPartialMatches(args[0], GAMEMODE_NAMES, new ArrayList<String>(GAMEMODE_NAMES.size()));
}
return ImmutableList.of();
}
}

View File

@@ -1,11 +1,18 @@
package org.bukkit.command.defaults;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import com.google.common.collect.ImmutableList;
public class DeopCommand extends VanillaCommand {
public DeopCommand() {
@@ -18,13 +25,11 @@ public class DeopCommand extends VanillaCommand {
@Override
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) return true;
if (args.length != 1) {
if (args.length != 1 || args[0].length() == 0) {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
Command.broadcastCommandMessage(sender, "De-opping " + args[0]);
OfflinePlayer player = Bukkit.getOfflinePlayer(args[0]);
player.setOp(false);
@@ -32,11 +37,26 @@ public class DeopCommand extends VanillaCommand {
((Player) player).sendMessage(ChatColor.YELLOW + "You are no longer op!");
}
Command.broadcastCommandMessage(sender, "De-opped " + args[0]);
return true;
}
@Override
public boolean matches(String input) {
return input.equalsIgnoreCase("deop");
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 1) {
List<String> completions = new ArrayList<String>();
for (OfflinePlayer player : Bukkit.getOperators()) {
String playerName = player.getName();
if (StringUtil.startsWithIgnoreCase(playerName, args[0])) {
completions.add(playerName);
}
}
return completions;
}
return ImmutableList.of();
}
}

View File

@@ -0,0 +1,81 @@
package org.bukkit.command.defaults;
import com.google.common.collect.ImmutableList;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.util.StringUtil;
import org.bukkit.Difficulty;
import java.util.ArrayList;
import java.util.List;
public class DifficultyCommand extends VanillaCommand {
private static final List<String> DIFFICULTY_NAMES = ImmutableList.of("peaceful", "easy", "normal", "hard");
public DifficultyCommand() {
super("difficulty");
this.description = "Sets the game difficulty";
this.usageMessage = "/difficulty <new difficulty> ";
this.setPermission("bukkit.command.difficulty");
}
@Override
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) return true;
if (args.length != 1 || args[0].length() == 0) {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
Difficulty difficulty = Difficulty.getByValue(getDifficultyForString(sender, args[0]));
if (Bukkit.isHardcore()) {
difficulty = Difficulty.HARD;
}
Bukkit.getWorlds().get(0).setDifficulty(difficulty);
int levelCount = 1;
if (Bukkit.getAllowNether()) {
Bukkit.getWorlds().get(levelCount).setDifficulty(difficulty);
levelCount++;
}
if (Bukkit.getAllowEnd()) {
Bukkit.getWorlds().get(levelCount).setDifficulty(difficulty);
}
Command.broadcastCommandMessage(sender, "Set difficulty to " + difficulty.toString());
return true;
}
protected int getDifficultyForString(CommandSender sender, String name) {
if (name.equalsIgnoreCase("peaceful") || name.equalsIgnoreCase("p")) {
return 0;
} else if (name.equalsIgnoreCase("easy") || name.equalsIgnoreCase("e")) {
return 1;
} else if (name.equalsIgnoreCase("normal") || name.equalsIgnoreCase("n")) {
return 2;
} else if (name.equalsIgnoreCase("hard") || name.equalsIgnoreCase("h")) {
return 3;
} else {
return getInteger(sender, name, 0, 3);
}
}
@Override
public List<String> tabComplete(CommandSender sender, String alias, String[] args) {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 1) {
return StringUtil.copyPartialMatches(args[0], DIFFICULTY_NAMES, new ArrayList<String>(DIFFICULTY_NAMES.size()));
}
return ImmutableList.of();
}
}

View File

@@ -0,0 +1,119 @@
package org.bukkit.command.defaults;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.List;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.StringUtil;
public class EffectCommand extends VanillaCommand {
private static final List<String> effects;
public EffectCommand() {
super("effect");
this.description = "Adds/Removes effects on players";
this.usageMessage = "/effect <player> <effect|clear> [seconds] [amplifier]";
this.setPermission("bukkit.command.effect");
}
static {
ImmutableList.Builder<String> builder = ImmutableList.<String>builder();
for (PotionEffectType type : PotionEffectType.values()) {
if (type != null) {
builder.add(type.getName());
}
}
effects = builder.build();
}
@Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
if (!testPermission(sender)) {
return true;
}
if (args.length < 2) {
sender.sendMessage(getUsage());
return true;
}
final Player player = sender.getServer().getPlayer(args[0]);
if (player == null) {
sender.sendMessage(ChatColor.RED + String.format("Player, %s, not found", args[0]));
return true;
}
if ("clear".equalsIgnoreCase(args[1])) {
for (PotionEffect effect : player.getActivePotionEffects()) {
player.removePotionEffect(effect.getType());
}
sender.sendMessage(String.format("Took all effects from %s", args[0]));
return true;
}
PotionEffectType effect = PotionEffectType.getByName(args[1]);
if (effect == null) {
effect = PotionEffectType.getById(getInteger(sender, args[1], 0));
}
if (effect == null) {
sender.sendMessage(ChatColor.RED + String.format("Effect, %s, not found", args[1]));
return true;
}
int duration = 600;
int duration_temp = 30;
int amplification = 0;
if (args.length >= 3) {
duration_temp = getInteger(sender, args[2], 0, 1000000);
if (effect.isInstant()) {
duration = duration_temp;
} else {
duration = duration_temp * 20;
}
} else if (effect.isInstant()) {
duration = 1;
}
if (args.length >= 4) {
amplification = getInteger(sender, args[3], 0, 255);
}
if (duration_temp == 0) {
if (!player.hasPotionEffect(effect)) {
sender.sendMessage(String.format("Couldn't take %s from %s as they do not have the effect", effect.getName(), args[0]));
return true;
}
player.removePotionEffect(effect);
broadcastCommandMessage(sender, String.format("Took %s from %s", effect.getName(), args[0]));
} else {
final PotionEffect applyEffect = new PotionEffect(effect, duration, amplification);
player.addPotionEffect(applyEffect, true);
broadcastCommandMessage(sender, String.format("Given %s (ID %d) * %d to %s for %d seconds", effect.getName(), effect.getId(), amplification, args[0], duration_temp));
}
return true;
}
@Override
public List<String> tabComplete(CommandSender sender, String commandLabel, String[] args) {
if (args.length == 1) {
return super.tabComplete(sender, commandLabel, args);
} else if (args.length == 2) {
return StringUtil.copyPartialMatches(args[1], effects, new ArrayList<String>(effects.size()));
}
return ImmutableList.of();
}
}

View File

@@ -0,0 +1,169 @@
package org.bukkit.command.defaults;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.WordUtils;
import com.google.common.collect.ImmutableList;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.StringUtil;
public class EnchantCommand extends VanillaCommand {
private static final List<String> ENCHANTMENT_NAMES = new ArrayList<String>();
public EnchantCommand() {
super("enchant");
this.description = "Adds enchantments to the item the player is currently holding. Specify 0 for the level to remove an enchantment. Specify force to ignore normal enchantment restrictions";
this.usageMessage = "/enchant <player> <enchantment> [level|max|0] [force]";
this.setPermission("bukkit.command.enchant");
}
@Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
if (!testPermission(sender)) return true;
if (args.length < 2) {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
boolean force = false;
if (args.length > 2) {
force = args[args.length > 3 ? 3 : 2].equalsIgnoreCase("force");
}
Player player = Bukkit.getPlayerExact(args[0]);
if (player == null) {
sender.sendMessage("Can't find player " + args[0]);
} else {
ItemStack item = player.getItemInHand();
if (item.getType() == Material.AIR) {
sender.sendMessage("The player isn't holding an item");
} else {
String itemName = item.getType().toString().replaceAll("_", " ");
itemName = WordUtils.capitalizeFully(itemName);
Enchantment enchantment = getEnchantment(args[1].toUpperCase());
if (enchantment == null) {
sender.sendMessage(String.format("Enchantment does not exist: %s", args[1]));
} else {
String enchantmentName = enchantment.getName().replaceAll("_", " ");
enchantmentName = WordUtils.capitalizeFully(enchantmentName);
if (!force && !enchantment.canEnchantItem(item)) {
sender.sendMessage(String.format("%s cannot be applied to %s", enchantmentName, itemName));
} else {
int level = 1;
if (args.length > 2) {
Integer integer = getInteger(args[2]);
int minLevel = enchantment.getStartLevel();
int maxLevel = force ? Short.MAX_VALUE : enchantment.getMaxLevel();
if (integer != null) {
if (integer == 0) {
item.removeEnchantment(enchantment);
Command.broadcastCommandMessage(sender, String.format("Removed %s on %s's %s", enchantmentName, player.getName(), itemName));
return true;
}
if (integer < minLevel || integer > maxLevel) {
sender.sendMessage(String.format("Level for enchantment %s must be between %d and %d", enchantmentName, minLevel, maxLevel));
sender.sendMessage("Specify 0 for level to remove an enchantment");
return true;
}
level = integer;
}
if ("max".equals(args[2])) {
level = maxLevel;
}
}
Map<Enchantment, Integer> enchantments = item.getEnchantments();
boolean conflicts = false;
if (!force && !enchantments.isEmpty()) { // TODO: Improve this to use a "hasEnchantments" call
for (Map.Entry<Enchantment, Integer> entry : enchantments.entrySet()) {
Enchantment enchant = entry.getKey();
if (enchant.equals(enchantment)) continue;
if (enchant.conflictsWith(enchantment)) {
sender.sendMessage(String.format("Can't apply the enchantment %s on an item with the enchantment %s", enchantmentName, WordUtils.capitalizeFully(enchant.getName().replaceAll("_", " "))));
conflicts = true;
break;
}
}
}
if (!conflicts) {
item.addUnsafeEnchantment(enchantment, level);
Command.broadcastCommandMessage(sender, String.format("Applied %s (Lvl %d) on %s's %s", enchantmentName, level, player.getName(), itemName), false);
sender.sendMessage(String.format("Enchanting succeeded, applied %s (Lvl %d) onto your %s", enchantmentName, level, itemName));
}
}
}
}
}
return true;
}
@Override
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 1) {
return super.tabComplete(sender, alias, args);
}
if (args.length == 2) {
return StringUtil.copyPartialMatches(args[1], ENCHANTMENT_NAMES, new ArrayList<String>(ENCHANTMENT_NAMES.size()));
}
if (args.length == 3 || args.length == 4) {
if (!args[args.length - 2].equalsIgnoreCase("force")) {
return ImmutableList.of("force");
}
}
return ImmutableList.of();
}
private Enchantment getEnchantment(String lookup) {
Enchantment enchantment = Enchantment.getByName(lookup);
if (enchantment == null) {
Integer id = getInteger(lookup);
if (id != null) {
enchantment = Enchantment.getById(id);
}
}
return enchantment;
}
public static void buildEnchantments() {
if (!ENCHANTMENT_NAMES.isEmpty()) {
throw new IllegalStateException("Enchantments have already been built!");
}
for (Enchantment enchantment : Enchantment.values()) {
ENCHANTMENT_NAMES.add(enchantment.getName());
}
Collections.sort(ENCHANTMENT_NAMES);
}
}

View File

@@ -1,48 +1,89 @@
package org.bukkit.command.defaults;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.google.common.collect.ImmutableList;
public class ExpCommand extends VanillaCommand {
public ExpCommand() {
super("xp");
this.description = "Gives the specified player a certain amount of experience";
this.usageMessage = "/xp <player> <amount>";
this.description = "Gives the specified player a certain amount of experience. Specify <amount>L to give levels instead, with a negative amount resulting in taking levels.";
this.usageMessage = "/xp <amount> [player] OR /xp <amount>L [player]";
this.setPermission("bukkit.command.xp");
}
@Override
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) return true;
if (args.length != 2) {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
Player player = Bukkit.getPlayerExact(args[0]);
if (args.length > 0) {
String inputAmount = args[0];
Player player = null;
if (player != null) {
try {
int exp = Integer.parseInt(args[1]);
Command.broadcastCommandMessage(sender, "Giving " + exp + " exp to " + player.getName());
player.giveExp(exp);
} catch (NumberFormatException ex) {
sender.sendMessage("Invalid exp count: " + args[1]);
boolean isLevel = inputAmount.endsWith("l") || inputAmount.endsWith("L");
if (isLevel && inputAmount.length() > 1) {
inputAmount = inputAmount.substring(0, inputAmount.length() - 1);
}
} else {
sender.sendMessage("Can't find user " + args[0]);
int amount = getInteger(sender, inputAmount, Integer.MIN_VALUE, Integer.MAX_VALUE);
boolean isTaking = amount < 0;
if (isTaking) {
amount *= -1;
}
if (args.length > 1) {
player = Bukkit.getPlayer(args[1]);
} else if (sender instanceof Player) {
player = (Player) sender;
}
if (player != null) {
if (isLevel) {
if (isTaking) {
player.giveExpLevels(-amount);
Command.broadcastCommandMessage(sender, "Taken " + amount + " level(s) from " + player.getName());
} else {
player.giveExpLevels(amount);
Command.broadcastCommandMessage(sender, "Given " + amount + " level(s) to " + player.getName());
}
} else {
if (isTaking) {
sender.sendMessage(ChatColor.RED + "Taking experience can only be done by levels, cannot give players negative experience points");
return false;
} else {
player.giveExp(amount);
Command.broadcastCommandMessage(sender, "Given " + amount + " experience to " + player.getName());
}
}
} else {
sender.sendMessage("Can't find player, was one provided?\n" + ChatColor.RED + "Usage: " + usageMessage);
return false;
}
return true;
}
return true;
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
@Override
public boolean matches(String input) {
return input.equalsIgnoreCase("xp");
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 2) {
return super.tabComplete(sender, alias, args);
}
return ImmutableList.of();
}
}

View File

@@ -1,63 +1,98 @@
package org.bukkit.command.defaults;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.GameMode;
import org.bukkit.util.StringUtil;
import com.google.common.collect.ImmutableList;
public class GameModeCommand extends VanillaCommand {
private static final List<String> GAMEMODE_NAMES = ImmutableList.of("adventure", "creative", "survival");
public GameModeCommand() {
super("gamemode");
this.description = "Changes the player to a specific game mode";
this.usageMessage = "/gamemode <player> <gamemode>";
this.usageMessage = "/gamemode <mode> [player]";
this.setPermission("bukkit.command.gamemode");
}
@Override
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) return true;
if (args.length != 2) {
if (args.length == 0) {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
Player player = Bukkit.getPlayerExact(args[0]);
String modeArg = args[0];
String playerArg = sender.getName();
if (args.length == 2) {
playerArg = args[1];
}
Player player = Bukkit.getPlayerExact(playerArg);
if (player != null) {
int value = -1;
try {
value = Integer.parseInt(args[1]);
value = Integer.parseInt(modeArg);
} catch (NumberFormatException ex) {}
GameMode mode = GameMode.getByValue(value);
if (mode != null) {
if (mode != player.getGameMode()) {
Command.broadcastCommandMessage(sender, "Setting " + player.getName() + " to game mode " + mode.getValue());
player.setGameMode(mode);
if (mode != player.getGameMode()) {
Command.broadcastCommandMessage(sender, "The game mode change for " + player.getName() + " was cancelled!");
}
if (mode == null) {
if (modeArg.equalsIgnoreCase("creative") || modeArg.equalsIgnoreCase("c")) {
mode = GameMode.CREATIVE;
} else if (modeArg.equalsIgnoreCase("adventure") || modeArg.equalsIgnoreCase("a")) {
mode = GameMode.ADVENTURE;
} else {
sender.sendMessage(player.getName() + " already has game mode " + mode.getValue());
mode = GameMode.SURVIVAL;
}
}
if (mode != player.getGameMode()) {
player.setGameMode(mode);
if (mode != player.getGameMode()) {
sender.sendMessage("Game mode change for " + player.getName() + " failed!");
} else {
if (player == sender) {
Command.broadcastCommandMessage(sender, "Set own game mode to " + mode.toString() + " mode");
} else {
Command.broadcastCommandMessage(sender, "Set " + player.getName() + "'s game mode to " + mode.toString() + " mode");
}
}
} else {
sender.sendMessage("There is no game mode with id " + args[1]);
sender.sendMessage(player.getName() + " already has game mode " + mode.getValue());
}
} else {
sender.sendMessage("Can't find user " + args[0]);
sender.sendMessage("Can't find player " + playerArg);
}
return true;
}
@Override
public boolean matches(String input) {
return input.equalsIgnoreCase("gamemode");
public List<String> tabComplete(CommandSender sender, String alias, String[] args) {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 1) {
return StringUtil.copyPartialMatches(args[0], GAMEMODE_NAMES, new ArrayList<String>(GAMEMODE_NAMES.size()));
} else if (args.length == 2) {
return super.tabComplete(sender, alias, args);
}
return ImmutableList.of();
}
}

View File

@@ -0,0 +1,88 @@
package org.bukkit.command.defaults;
import com.google.common.collect.ImmutableList;
import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor;
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.util.StringUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.entity.HumanEntity;
public class GameRuleCommand extends VanillaCommand {
private static final List<String> GAMERULE_STATES = ImmutableList.of("true", "false");
public GameRuleCommand() {
super("gamerule");
this.description = "Sets a server's game rules";
this.usageMessage = "/gamerule <rule name> <value> OR /gamerule <rule name>";
this.setPermission("bukkit.command.gamerule");
}
@Override
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) return true;
if (args.length > 0) {
String rule = args[0];
World world = getGameWorld(sender);
if (world.isGameRule(rule)) {
if (args.length > 1) {
String value = args[1];
world.setGameRuleValue(rule, value);
Command.broadcastCommandMessage(sender, "Game rule " + rule + " has been set to: " + value);
} else {
String value = world.getGameRuleValue(rule);
sender.sendMessage(rule + " = " + value);
}
} else {
sender.sendMessage(ChatColor.RED + "No game rule called " + rule + " is available");
}
return true;
} else {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
sender.sendMessage("Rules: " + this.createString(getGameWorld(sender).getGameRules(), 0, ", "));
return true;
}
}
private World getGameWorld(CommandSender sender) {
if (sender instanceof HumanEntity) {
World world = ((HumanEntity) sender).getWorld();
if (world != null) {
return world;
}
} else if (sender instanceof BlockCommandSender) {
return ((BlockCommandSender) sender).getBlock().getWorld();
}
return Bukkit.getWorlds().get(0);
}
@Override
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 1) {
return StringUtil.copyPartialMatches(args[0], Arrays.asList(getGameWorld(sender).getGameRules()), new ArrayList<String>());
}
if (args.length == 2) {
return StringUtil.copyPartialMatches(args[1], GAMERULE_STATES, new ArrayList<String>(GAMERULE_STATES.size()));
}
return ImmutableList.of();
}
}

View File

@@ -1,5 +1,11 @@
package org.bukkit.command.defaults;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
@@ -7,8 +13,22 @@ import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.util.StringUtil;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
public class GiveCommand extends VanillaCommand {
private static List<String> materials;
static {
ArrayList<String> materialList = new ArrayList<String>();
for (Material material : Material.values()) {
materialList.add(material.name());
}
Collections.sort(materialList);
materials = ImmutableList.copyOf(materialList);
}
public GiveCommand() {
super("give");
this.description = "Gives the specified player a certain amount of items";
@@ -19,7 +39,7 @@ public class GiveCommand extends VanillaCommand {
@Override
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) return true;
if ((args.length < 2) || (args.length > 4)) {
if ((args.length < 2)) {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
@@ -29,19 +49,17 @@ public class GiveCommand extends VanillaCommand {
if (player != null) {
Material material = Material.matchMaterial(args[1]);
if (material != null) {
Command.broadcastCommandMessage(sender, "Giving " + player.getName() + " some " + material.getId() + " (" + material + ")");
if (material == null) {
material = Bukkit.getUnsafe().getMaterialFromInternalName(args[1]);
}
if (material != null) {
int amount = 1;
short data = 0;
if (args.length >= 3) {
try {
amount = Integer.parseInt(args[2]);
} catch (NumberFormatException ex) {}
amount = this.getInteger(sender, args[2], 1, 64);
if (amount < 1) amount = 1;
if (amount > 64) amount = 64;
if (args.length >= 4) {
try {
data = Short.parseShort(args[3]);
@@ -49,19 +67,63 @@ public class GiveCommand extends VanillaCommand {
}
}
player.getInventory().addItem(new ItemStack(material, amount, data));
ItemStack stack = new ItemStack(material, amount, data);
if (args.length >= 5) {
try {
stack = Bukkit.getUnsafe().modifyItemStack(stack, Joiner.on(' ').join(Arrays.asList(args).subList(4, args.length)));
} catch (Throwable t) {
player.sendMessage("Not a valid tag");
return true;
}
}
player.getInventory().addItem(stack);
Command.broadcastCommandMessage(sender, "Gave " + player.getName() + " some " + material.getId() + " (" + material + ")");
} else {
sender.sendMessage("There's no item called " + args[1]);
}
} else {
sender.sendMessage("Can't find user " + args[0]);
sender.sendMessage("Can't find player " + args[0]);
}
return true;
}
@Override
public boolean matches(String input) {
return input.equalsIgnoreCase("give");
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 1) {
return super.tabComplete(sender, alias, args);
}
if (args.length == 2) {
final String arg = args[1];
final List<String> materials = GiveCommand.materials;
List<String> completion = new ArrayList<String>();
final int size = materials.size();
int i = Collections.binarySearch(materials, arg, String.CASE_INSENSITIVE_ORDER);
if (i < 0) {
// Insertion (start) index
i = -1 - i;
}
for ( ; i < size; i++) {
String material = materials.get(i);
if (StringUtil.startsWithIgnoreCase(material, arg)) {
completion.add(material);
} else {
break;
}
}
return Bukkit.getUnsafe().tabCompleteInternalMaterialName(arg, completion);
}
return ImmutableList.of();
}
}

View File

@@ -1,7 +1,16 @@
package org.bukkit.command.defaults;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.math.NumberUtils;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
@@ -13,13 +22,14 @@ import org.bukkit.help.HelpTopicComparator;
import org.bukkit.help.IndexHelpTopic;
import org.bukkit.util.ChatPaginator;
import java.util.*;
import com.google.common.collect.ImmutableList;
public class HelpCommand extends VanillaCommand {
public HelpCommand() {
super("help");
this.description = "Shows the help menu";
this.usageMessage = "/help <pageNumber>\n/help <topic>\n/help <topic> <pageNumber>";
this.setAliases(Arrays.asList(new String[] { "?" }));
this.setPermission("bukkit.command.help");
}
@@ -102,8 +112,24 @@ public class HelpCommand extends VanillaCommand {
}
@Override
public boolean matches(String input) {
return input.equalsIgnoreCase("help") || input.equalsIgnoreCase("?");
public List<String> tabComplete(CommandSender sender, String alias, String[] args) {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 1) {
List<String> matchedTopics = new ArrayList<String>();
String searchString = args[0];
for (HelpTopic topic : Bukkit.getServer().getHelpMap().getHelpTopics()) {
String trimmedTopic = topic.getName().startsWith("/") ? topic.getName().substring(1) : topic.getName();
if (trimmedTopic.startsWith(searchString)) {
matchedTopics.add(trimmedTopic);
}
}
return matchedTopics;
}
return ImmutableList.of();
}
protected HelpTopic findPossibleMatches(String searchString) {

View File

@@ -1,23 +1,28 @@
package org.bukkit.command.defaults;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.google.common.collect.ImmutableList;
public class KickCommand extends VanillaCommand {
public KickCommand() {
super("kick");
this.description = "Removes the specified player from the server";
this.usageMessage = "/kick <player>";
this.usageMessage = "/kick <player> [reason ...]";
this.setPermission("bukkit.command.kick");
}
@Override
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) return true;
if (args.length < 1) {
if (args.length < 1 || args[0].length() == 0) {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
@@ -25,17 +30,30 @@ public class KickCommand extends VanillaCommand {
Player player = Bukkit.getPlayerExact(args[0]);
if (player != null) {
Command.broadcastCommandMessage(sender, "Kicking " + player.getName());
player.kickPlayer("Kicked by admin");
String reason = "Kicked by an operator.";
if (args.length > 1) {
reason = createString(args, 1);
}
player.kickPlayer(reason);
Command.broadcastCommandMessage(sender, "Kicked player " + player.getName() + ". With reason:\n" + reason);
} else {
sender.sendMessage("Can't find user " + args[0] + ". No kick.");
sender.sendMessage( args[0] + " not found.");
}
return true;
}
@Override
public boolean matches(String input) {
return input.equalsIgnoreCase("kick");
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length >= 1) {
return super.tabComplete(sender, alias, args);
}
return ImmutableList.of();
}
}

View File

@@ -1,10 +1,15 @@
package org.bukkit.command.defaults;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.entity.EntityDamageEvent;
import com.google.common.collect.ImmutableList;
public class KillCommand extends VanillaCommand {
public KillCommand() {
super("kill");
@@ -24,7 +29,9 @@ public class KillCommand extends VanillaCommand {
Bukkit.getPluginManager().callEvent(ede);
if (ede.isCancelled()) return true;
player.damage(ede.getDamage());
ede.getEntity().setLastDamageCause(ede);
player.setHealth(0);
sender.sendMessage("Ouch. That look like it hurt.");
} else {
sender.sendMessage("You can only perform this command as a player");
}
@@ -33,7 +40,11 @@ public class KillCommand extends VanillaCommand {
}
@Override
public boolean matches(String input) {
return input.equalsIgnoreCase("kill");
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
return ImmutableList.of();
}
}

View File

@@ -1,9 +1,15 @@
package org.bukkit.command.defaults;
import java.util.Collection;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.google.common.collect.ImmutableList;
public class ListCommand extends VanillaCommand {
public ListCommand() {
super("list");
@@ -16,27 +22,33 @@ public class ListCommand extends VanillaCommand {
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) return true;
StringBuilder players = new StringBuilder();
StringBuilder online = new StringBuilder();
for (Player player : Bukkit.getOnlinePlayers()) {
final Collection<? extends Player> players = Bukkit.getOnlinePlayers();
for (Player player : players) {
// If a player is hidden from the sender don't show them in the list
if (sender instanceof Player && !((Player) sender).canSee(player))
continue;
if (players.length() > 0) {
players.append(", ");
if (online.length() > 0) {
online.append(", ");
}
players.append(player.getDisplayName());
online.append(player.getDisplayName());
}
sender.sendMessage("Connected players: " + players.toString());
sender.sendMessage("There are " + players.size() + "/" + Bukkit.getMaxPlayers() + " players online:\n" + online.toString());
return true;
}
@Override
public boolean matches(String input) {
return input.equalsIgnoreCase("list");
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
return ImmutableList.of();
}
}

View File

@@ -22,20 +22,14 @@ public class MeCommand extends VanillaCommand {
StringBuilder message = new StringBuilder();
message.append(sender.getName());
if (args.length > 0) {
for (String arg : args) {
message.append(" ");
message.append(arg);
}
for (String arg : args) {
message.append(" ");
message.append(arg);
}
Bukkit.broadcastMessage("* " + message.toString());
return true;
}
@Override
public boolean matches(String input) {
return input.equalsIgnoreCase("me");
}
}

View File

@@ -1,11 +1,19 @@
package org.bukkit.command.defaults;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import com.google.common.collect.ImmutableList;
public class OpCommand extends VanillaCommand {
public OpCommand() {
@@ -18,25 +26,50 @@ public class OpCommand extends VanillaCommand {
@Override
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) return true;
if (args.length != 1) {
if (args.length != 1 || args[0].length() == 0) {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
Command.broadcastCommandMessage(sender, "Opping " + args[0]);
OfflinePlayer player = Bukkit.getOfflinePlayer(args[0]);
player.setOp(true);
if (player instanceof Player) {
((Player) player).sendMessage(ChatColor.YELLOW + "You are now op!");
}
Command.broadcastCommandMessage(sender, "Opped " + args[0]);
return true;
}
@Override
public boolean matches(String input) {
return input.equalsIgnoreCase("op");
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 1) {
if (!(sender instanceof Player)) {
return ImmutableList.of();
}
String lastWord = args[0];
if (lastWord.length() == 0) {
return ImmutableList.of();
}
Player senderPlayer = (Player) sender;
ArrayList<String> matchedPlayers = new ArrayList<String>();
for (Player player : sender.getServer().getOnlinePlayers()) {
String name = player.getName();
if (!senderPlayer.canSee(player) || player.isOp()) {
continue;
}
if (StringUtil.startsWithIgnoreCase(name, lastWord)) {
matchedPlayers.add(name);
}
}
Collections.sort(matchedPlayers, String.CASE_INSENSITIVE_ORDER);
return matchedPlayers;
}
return ImmutableList.of();
}
}

View File

@@ -1,9 +1,18 @@
package org.bukkit.command.defaults;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.bukkit.BanList;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.util.StringUtil;
import com.google.common.collect.ImmutableList;
public class PardonCommand extends VanillaCommand {
public PardonCommand() {
@@ -21,14 +30,27 @@ public class PardonCommand extends VanillaCommand {
return false;
}
Bukkit.getOfflinePlayer(args[0]).setBanned(false);
Command.broadcastCommandMessage(sender, "Pardoning " + args[0]);
Bukkit.getBanList(BanList.Type.NAME).pardon(args[0]);
Command.broadcastCommandMessage(sender, "Pardoned " + args[0]);
return true;
}
@Override
public boolean matches(String input) {
return input.equalsIgnoreCase("pardon");
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 1) {
List<String> completions = new ArrayList<String>();
for (OfflinePlayer player : Bukkit.getBannedPlayers()) {
String name = player.getName();
if (StringUtil.startsWithIgnoreCase(name, args[0])) {
completions.add(name);
}
}
return completions;
}
return ImmutableList.of();
}
}

View File

@@ -1,9 +1,16 @@
package org.bukkit.command.defaults;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.util.StringUtil;
import com.google.common.collect.ImmutableList;
public class PardonIpCommand extends VanillaCommand {
public PardonIpCommand() {
@@ -21,14 +28,25 @@ public class PardonIpCommand extends VanillaCommand {
return false;
}
Bukkit.unbanIP(args[0]);
Command.broadcastCommandMessage(sender, "Pardoning ip " + args[0]);
if (BanIpCommand.ipValidity.matcher(args[0]).matches()) {
Bukkit.unbanIP(args[0]);
Command.broadcastCommandMessage(sender, "Pardoned ip " + args[0]);
} else {
sender.sendMessage("Invalid ip");
}
return true;
}
@Override
public boolean matches(String input) {
return input.equalsIgnoreCase("pardon-ip");
public List<String> tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException {
Validate.notNull(sender, "Sender cannot be null");
Validate.notNull(args, "Arguments cannot be null");
Validate.notNull(alias, "Alias cannot be null");
if (args.length == 1) {
return StringUtil.copyPartialMatches(args[0], Bukkit.getIPBans(), new ArrayList<String>());
}
return ImmutableList.of();
}
}

View File

@@ -0,0 +1,87 @@
package org.bukkit.command.defaults;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class PlaySoundCommand extends VanillaCommand {
public PlaySoundCommand() {
super("playsound");
this.description = "Plays a sound to a given player";
this.usageMessage = "/playsound <sound> <player> [x] [y] [z] [volume] [pitch] [minimumVolume]";
this.setPermission("bukkit.command.playsound");
}
@Override
public boolean execute(CommandSender sender, String currentAlias, String[] args) {
if (!testPermission(sender)) {
return true;
}
if (args.length < 2) {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
final String soundArg = args[0];
final String playerArg = args[1];
final Player player = Bukkit.getPlayerExact(playerArg);
if (player == null) {
sender.sendMessage(ChatColor.RED + "Can't find player " + playerArg);
return false;
}
final Location location = player.getLocation();
double x = Math.floor(location.getX());
double y = Math.floor(location.getY() + 0.5D);
double z = Math.floor(location.getZ());
double volume = 1.0D;
double pitch = 1.0D;
double minimumVolume = 0.0D;
switch (args.length) {
default:
case 8:
minimumVolume = getDouble(sender, args[7], 0.0D, 1.0D);
case 7:
pitch = getDouble(sender, args[6], 0.0D, 2.0D);
case 6:
volume = getDouble(sender, args[5], 0.0D, Float.MAX_VALUE);
case 5:
z = getRelativeDouble(z, sender, args[4]);
case 4:
y = getRelativeDouble(y, sender, args[3]);
case 3:
x = getRelativeDouble(x, sender, args[2]);
case 2:
// Noop
}
final double fixedVolume = volume > 1.0D ? volume * 16.0D : 16.0D;
final Location soundLocation = new Location(player.getWorld(), x, y, z);
if (location.distanceSquared(soundLocation) > fixedVolume * fixedVolume) {
if (minimumVolume <= 0.0D) {
sender.sendMessage(ChatColor.RED + playerArg + " is too far away to hear the sound");
return false;
}
final double deltaX = x - location.getX();
final double deltaY = y - location.getY();
final double deltaZ = z - location.getZ();
final double delta = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ) / 2.0D;
if (delta > 0.0D) {
location.add(deltaX / delta, deltaY / delta, deltaZ / delta);
}
player.playSound(location, soundArg, (float) minimumVolume, (float) pitch);
} else {
player.playSound(soundLocation, soundArg, (float) volume, (float) pitch);
}
sender.sendMessage(String.format("Played '%s' to %s", soundArg, playerArg));
return true;
}
}

View File

@@ -1,9 +1,9 @@
package org.bukkit.command.defaults;
import java.util.Arrays;
import org.bukkit.ChatColor;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.Plugin;

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