When a world is created using our API, it does not use secondary world
server and will maintain a reference to its own scoreboard. In vanilla,
this is not an issue as there is only ever one world.
Similarly to maps, an overwrite to the scoreboard reference has been
added for when another world has been created.
This should also address BUKKIT-3982 and BUKKIT-3985
In commit 7710efc5f9 we corrected the handling of large chests as the
destination for hoppers moving items but did not apply the same fix for
large chests being the source or for droppers. This commit updates these
to have the same fix.
This implementation facilitates the correspondence of the Bukkit Scoreboard
API to the internal minecraft implementation.
When the first scoreboard is loaded, the scoreboard manager will be created.
It uses the newly added WeakCollection for handling plugin scoreboard
references to update the respective objectives. When a scoreboard contains no
more active references, it should be garbage collected.
An active reference can be held by a still registered objective, team, and
transitively a score for a still registered objective. An internal reference
will also be kept if a player's specific scoreboard has been set, and will
remain persistent until that player logs out.
A player's specific scoreboard becomes the scoreboard used when determining
team structure for the player's attacking damage and the player's vision.
This class is designed to be an invisible layer between a normal collection,
and one that silently loses entries because they are only weakly referencable.
Some operations have additional overhead to be semantically correct, but it
maintains the equals contract for all entries, as opposed to identity.
It does not support the equals or hash code method as it cannot easily have
the transitive and commutative properties.
This adds calls to BlockRedstoneEvent for the new daylight sensor and
trapped chest blocks. Note that the redstone level for trapped chests
cannot be modified, as it is based on the number of players currently
viewing the chest's inventory.
When an array of an inventory's contents is requested, we loop through the contents of the NMS inventory's ItemStacks in order to return Bukkit ItemStacks that can be used through the API. However, the NMS ItemStack can, in some cases, be larger than the physical size of the inventory. Using the size of the NMS array as a limit on the loop that follows can result in an ArrayIndexOutOfBoundsException because the Bukkit array's length is the actual size of the inventory, and thus will be smaller.
With this commit we use the smaller of the two arrays' length as the limit in the loop, thus eliminating the possibility that the smaller array will be asked for an index higher than its length.
When a block placement happens we currently update physics on the
attempted placement and update again if the placement is cancelled.
To correct the first one we simply set the block without applying
physics. To correct the second we have to add a new method to
BlockState that lets us update without applying physics and use
this method method when putting the block back.
Without this check, any non-null reference to a plugin is considered
'valid' for registering a task in the scheduler. This is obviously
unintentional behavior and has been changed to throw an
IllegalPluginAccessException. It is now consistent with the
SimplePluginManager event registration contract.
This in affect also addresses BUKKIT-3950 for uninitialized plugin
references (ones without a description).
Large chests work in a different fashion as they are a combination of
two other inventories. This causes their getOwner method to always return
null as their is no correct return. To compensate for this for the hopper
events we special case them to use their CraftBukkit counterpart that has
the information we need for the event.
When a splash potion has no applicable effects we currently do not call
PotionSplashEvent. This means plugins are unable to make custom
potions with reliable splash handling as they have to relicate the
functionality themselves.
With this commit we simply make the event fire regardless of the effects
on the potion.
When cloning an item, all references are copied to the new item. For
collections, this makes internal changes become visible in both the old and
new items.
In CraftMetaItem, clone was not making copies of the appropriate collections
and has been fixed for non-null values.
In CraftMetaEnchantedBook and CraftMetaPotion, clone was using possible empty
collection references and has been changed to explicitly null-check instead.
I should try to compile before I say "this change is okay".
I should try to compile before I say "this change is okay".
I should try to compile before I say "this change is okay".
I should try to compile before I say "this change is okay".
for i in range(100)
This causes the server to generate PrepareItemEnchantEvent even in the
case that an item is already enchanted or otherwise would normally not
be enchantable.
The client resets all formatting after a color code is received, but currently the ANSI codes do not, and so the console does not accurately reflect the appearance of the formatted text. Instead, the ANSI color codes are now set to reset all text attributes.
Currently when dealing with physical interactions with pressure plates
and tripwires we immediately block their activation as soon as a single
entity involved has their event cancelled. We also fire events whenever
an entity intersects the block a wooden button is in even if they aren't
actually pressing it. To correct this we move the button interaction to
the correct place and modify all three to only block the activation if
every entity is blocked from using them instead of just one of them.
CraftServer methods that implement the Server interface will throw an
IllegalArgumentException if a method cannot operate on a null input
and given a null pointer.
This causes methods to fail early and identify that a plugin is
responsible for passing in an invalid argument. This will only
change the exception thrown, if there originally was a thrown
exception. This helps with hunting down legitimate problems
with CraftBukkit.
If the server changes the weather it will set the per-player weather
variable and future changes will not apply. We should only set this
variable when a plugin is requesting per-player weather and not when
the server it doing it.
We used to fall Item.filterData() for this but that method is meant for
converting item data to block data during placement and does the wrong
thing for this case. Instead we just see if the item should have data and
if not set it to zero. We also have to filter wool data explicitly because
clients crash when given invalid wool data.
In Minecraft 1.5 saplings do not grow with a single use of bonemeal anymore.
Our code assumes they will and only takes away bonemeal from the player
when the tree grows successfully (not cancelled by a plugin). Instead we
now always remove a bonemeal even if a plugin is the reason a tree didn't
grow as this matches the vanilla logic more closely.
If a custom TravelAgent is used and returns null for findOrCreate method
a NullPointerException will occur.
Conflicts:
src/main/java/net/minecraft/server/PlayerList.java
Currently, CraftTravelAgent will call s() on the passed-in WorldServer in order to set DEFAULT. However, s() will always return null at this point, because WorldServer.P will still be null, as it is set after the constructor is called. Instead, we set CraftTravelAgent.DEFAULT to the instance that is being constructed.
Recent changes caused PlayerPortalEvent to suddenly return null
unexpectedly and could end up in NPEs resulting that did not before.
This commit addresses that situation by always ensuring a TravelAgent
instance is returned.
The TravelAgent for world 0 is returned arbitrarily in an effort to
compensate for plugins that are implementation dependent and expect some
form of a TravelAgent to be accessible in the event at all times.
Vanilla does not check for blocks in which the player could
suffocate when changing dimension, so portals will happily spawn
players in blocks when using a portal under certain
circumstances. However, we currently check for these instances
and move the player up until they will not suffocate. This means
that players can sometimes be taken to above the target portal,
making it seem as if a portal was not created. Instead, we now
disable this suffocation check when moveToWorld is called from
changeDimension, mirroring vanilla behavior more accurately.
Due to the having to generate new logic to avoid using the customized
PlayerConnection.moveToWorld, entities returning from The End were not
properly calculating their exit target. This commit corrects that
logic.
By having a single function to process BlockPlacement logic, we make
it so that there is consistent behavior throughout all BlockPlace
events. This should allow for easier troubleshooting and less diffs
in source.
This also fixes BUKKIT-3463 by including the correct coordinates that
were clicked to the event.
Also fixes: BUKKIT-3477 and BUKKIT-3488
Minecraft likes to double check that tile entities get set after they
are placed, however we didn't set tile entities until after our event
was called. This caused the world to have multiple tile entities in a
single block location; to fix this we now set tile entities before
the event.
When the skull BlockPlaceEvent was added it was made so the event
would be called after all the data has been set, however this is a
behavior change that is inconsistent with other BlockPlaceEvents.
Instead, if people wish to get the block data they should schedule
a task.
Relates to: BUKKIT-3438
When either of those settings are false, the worlds are not loaded and
therefore will not be targeted for portal exits. Existing worlds are
iterated directly to avoid defaulting to the first world if a direct
dimension match is not found.
Plugins must also specify exit from custom Bukkit worlds to comply with
original commit: https://github.com/Bukkit/CraftBukkit/commit/2dc2af0
This commit introduces a constant to clarify the dependency on the
CraftBukkit implementation of custom worlds having a dimension offset.
By returning the following value (7) we remove the need to special
case pistons in any way (other than the original purpose of this
check, which is to ensure pistons have valid data)
The previous logic was faulty since it lost the logic of "placing" the
block. It was also taking into account data that could have been
changed outside of the processing of this event, which is irrelevant
to the processing of this event.
The javadocs state that a null may be used to remove the currently
playing sound, however this causes a NullPointerException.
It also doesn't process registering the record correctly, along with
processing non-valid items.
By using return 0, we exit the loop prematurely preventing other
creature types from being spawned if one type is set to 0. By using
continue we move on to the other types and allow them to spawn
properly.
Fixes BUKKIT-3408, BUKKIT-3190, BUKKIT-3191, BUKKIT-3407
These changes relate mostly to semantical changes for serialization
contract, exception of changing the map scaling value from byte to boolean,
what it should have been in the first place. Appropriate unit tests were
added for CraftMapMeta, as they were missing.
This makes it so animals (tame or not) will sit properly and not move
around.
Wild animals that are sitting may override the sitting position if
they are attacking.
The 'tag' NBTTagCompound field of the ItemStack assumes that it is OK to
save a reference to an NBT supplied via load() and assumes it is OK to
supply a reference to the internal field during a save(). Neither is true,
as Chunk NBT structures are required to be read-only once created (due to
being written asynchronously off the server thread AND due to the potential
to be passed to a new Chunk if the same chunk is reloaded before the
writing of the NBT is completed by the File I/O thread). Keeping a live
reference to the NBT copy passed in, or to the NBT value passed back
during saving, creates serious thread safety issues which can result in
corrupted data being written to the world data files.
The specific issue here was uncovered by the recent change to use
setName("") on the ItemStack.tag object. When a chunk is being loaded
again before its save is completed, this results in name of the field
in the NBT being set to "". This causes it to be saved as "" instead
of "tag" resulting in it not being properly reloaded in the future which
results in the itemstack losing all of its metadata.
Teleportation should never be processed on dead entities. If you wish
to teleport an entity, do it on a living entity. If you wish to
teleport a player, set their respawn location in PlayerRespawnEvent.
This adds two settings to bukkit.yml, allowing activation and control of
two chunk garbage collection triggering conditions:
chunk-gc/period-in-ticks controls a periodic GC, run once every N ticks
(default is 600); chunk-gc/load-threshold causes the GC to run once
after every N calls to loadChunk() on a given world (this call is an API
call used by plugins, and is distinct from the path taken for routine
player movement-based loading). In both cases, setting to zero will
disable the given GC scheduling strategy.
In either case, the act of doing the GC is simply one of scanning the
loaded chunks, seeing which are NOT being used by one or more players
(due to view-distance) and which are not already queued for unload, and
queueing them for a normal unload. Ultimately, the unload is then
processed the same as if the chunk were unloaded due to leaving the
view-distance range of all players, so the impact on plugins should be
no different (and strategies such as handling the ChunkUnloadEvent in
order to prevent unload will still work).
The initial interval for the periodic GC is randomized on a per-world
basis, in order to avoid all world being GCed at the same time -
minimizing potential lag spikes.
With the persistence api introduced, pets did not have their
persistence flag updated to reflect their persistence. This caused
tame ocelots to not persist under specific conditions.
Slimes and wolves have health that can change based on certain
conditions. So we check if their max health should be updated, and if
it has been customized in any way.
We also scale the wolf's health for their tail
An ItemStack gains the tag name "tag" when the stack is serialized
to NBT, however items don't have a tag *until* they are serialized at
least once. So to solve this, we remove the tag name when loading the
NBT data.
Another problem with NBT are TagLists, when transferring tag lists
between the server and the client the names are lost, and so we
simply don't add a name to the tag.
If you cancel a BlockPlaceEvent for a sign the world is updated as if
the block was placed and then destroyed. To avoid this we set the block
without updating physics then apply the update after the event.
When unloading chunks we have a check to ensure we do not remove players
from the world due to the issues this would cause. However, our check
to see if the player is in this chunk is reversed and is in fact entirely
wrong. Even if the player isn't currently in this chunk we do not want
to remove them as that will still cause the same issues.
The key "direction" incorrectly mapped to variables that were already
set in the entity. In order to prevent loading incorrect data we
renamed "direction" to "power."
The player would have no permissions (other than their OP status)
when checked in the Quit event. This is because we removed permissions
before the event occurred. By calling it afterwards, we can persist
the data until the server finally removes the player.
In some situations, an async task could be cancelled with no tasks
pending. This means the finally {} block from run() never gets executed
properly on the last async task to have run, as it expected to be
executed again.
This fix takes the only spot that the task period is set to cancelled
and will check to see if the task should be purged from the runners
list.
Some meta functionality is refactored into common methods.
CraftItemStack uses the ItemMetaKey identifiers for enchantments.
Refactored unit test to include extra functionality; initially only
checking the presence of the DelegateDeserialization annotation.
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.
With 1.4, entity sound tracking changed for the better.
Our previous method additions can now be removed.
All that's left is checking if the source can be seen
by the recipient of the sound packet. Thanks, Mojang!
The purpose of the isSimilar method was designed to consider all NBT
data, not solely enchantments, without the need to have exact stack
size matches. The respective methods in CraftInventory were still
comparing enchantments instead of the ItemMeta.
Changes some NPEs to IllegalArgumentExceptions for exception consistency.
Contains(ItemStack, int) correctly calculates number of ItemStacks.
Adds a containsAtLeast(ItemStack, int) for finding a combined amount of a
single similar ItemStack.
Makes some utility methods private to prevent ambiguity in use.
When a player triggers a chunk load via walking around or teleporting there
is no need to stop everything and get this chunk on the main thread. The
client is used to having to wait some time for this chunk and the server
doesn't immediately do anything with it except send it to the player. At
the same time chunk loading is the last major source of file IO that still
runs on the main thread.
These two facts make it possible to offload chunks loaded for this reason
to another thread. However, not all parts of chunk loading can happen off
the main thread. For this we use the new AsynchronousExecutor system to
split chunk loading in to three pieces. The first is loading data from
disk, decompressing it, and parsing it in to an NBT structure. The second
piece is creating entities and tile entities in the chunk and adding them
to the world, this is still done on the main thread. The third piece is
informing everyone who requested a chunk load that the load is finished.
For this we register callbacks and then run them on the main thread once
the previous two stages are finished.
There are still cases where a chunk is needed immediately and these will
still trigger chunk loading entirely on the main thread. The most obvious
case is plugins using the API to request a chunk load. We also must load
the chunk immediately when something in the world tries to access it. In
these cases we ignore any possibly pending or in progress chunk loading
that is happening asynchronously as we will have the chunk loaded by the
time they are finished.
The hope is that overall this system will result in less CPU time and
pauses due to blocking file IO on the main thread thus giving more
consistent performance. Testing so far has shown that this also speeds up
chunk loading client side although some of this is likely to be because
we are sending less chunks at once for the client to process.
Thanks for @ammaraskar for help with the implementation of this feature.
When a player has canPickUpLoot set to true the code for mob pickup is
triggerd which does not know how to deal with player inventory. Since
players have their own logic for picking up items we simply disable this
code for them.
The old flag for picking up loot was default to false, making existing players not able to pickup items. We now use this flag for Players, which gives us the problem we had in 48b46f83.
To fix this, we add an incremental flag that will be cross-examined to check if the data was saved before or after the flag level was introduced.
Addresses BUKKIT-3143
As an added feature, players defaulted to being able to not pick up items if the flag was false. However, since minecraft doesn't normally use the flag on players, the flag was always false.
Adds:
- Getting/Setting equipment
- getting/setting drop rates
- getting/setting ability to pick up items
-- As an added feature, players with this flag start off with a canceled PlayerPickupItemEvent