Hey, I am thinking about using this in this scenario:
Scenario: Players playing paintball (player try to hit the other teams player with snowball by throwing them/using "weapons" that spawn snowballs)
Currently:
Player throws snowball-> I check if the player is playing paintball -> snowball gets some boost up etc.
Player (which is playing paintball) receives damage by a snowball -> check: is the shooter of the snowball playing paintball ? -> get Team information of the shooter -> is shooter still "alive/in-game" ? (Already hit players can't hit other players) -> play some effects (depending on team), mark the player as hit, print some "playerA hit playerB"-message

Now, I am thinking about differing between different snowball sources (to print different hit messages for example), like one time a player directly throws the snowball and an other time the snowball is spawned by some "grenade-egg".

Ideas:
- store the snowballs in different list and check inside that list later on hit, to see if it comes from a special source
- or: using metadata, to tag the snowball as "paintball" already on creation with source (and maybe team(color)) information:

Player (which is playing paintball) receives damage by a snowball -> check: is the snowball tagged with "paintball" ? -> Check: is the shooter playing paintball ? -> Check: is the shooter still "alive" in the game - > get get source and team-color information from metadata tags -> play some effects (depending on team), mark the player as hit, print some "playerA hit playerB by <source>"-message

I'm having difficulty gleaning any information about how to access the datatags on LivingEntities (for example, accessing catType on an Ozelot). Is it simply getMetadata(someOzelot, catType)? I'm mostly interested in how to get/set horse data once 1.6 is live and bukkit is updated. I know many of them are able to be changed with methods (Pig - setSaddle). Is it known if type/coloration/health/armor/chested/jump strentgh/speed methods will be provided?

I'm having difficulty gleaning any information about how to access the datatags on LivingEntities (for example, accessing catType on an Ozelot). Is it simply getMetadata(someOzelot, catType)?

Click to expand...

The Metadata API is for setting arbitrary metadata on many types of objects (blocks, entities, worlds, players) that is keyed on a string. These metadatas are meant for plugins to store data that other plugins can retrieve. Nothing in the core bukkit API will use any of those metadata for in-game values.

Now, what you appear to be asking about with catType is a matter of methods on the sub-types. In order to get the methods on a specific type of entity you will need to upcast the entity to the appropriate type. For example, say you have an Entity named entity:

Code:java

if(entity.getType()== EntityType.OCELOT){

Ocelot ocelot =(Ocelot) entity

if(ocelot.getCatType()== Ocelot.Type.RED_CAT){

// do something

}

}

Similarly, you can add checks like this before upcasting to other specific type classes. If you try to upcast to Ocelot with an entity which isn't an Ocelot, you will get a ClassCastException.

I'm mostly interested in how to get/set horse data once 1.6 is live and bukkit is updated.

Click to expand...

When 1.6 exists, and bukkit updates to 1.6, there will probably be a Horse class. What methods it contains depends on how much work someone is willing to do, and to some extent, the limitations of bukkit in how it can effect the operation of this.

Is it known if type/coloration/health/armor/chested/jump strentgh/speed methods will be provided?

Click to expand...

You can already update the health and armor on many living entities. Type/coloration varies, you can change ocelots between the available colors of cats, for example. Beyond that, it depends. Jump strength and speed are not really something that's easy to change, as it involves modifying the AI of the mob.

There is almost no value in this API in the current state. I'm looking forward to using it when metadata gets persisted with the item. This is a half baked implementation.

Click to expand...

It is half baked, and I have been working along with the bukkit devs to change / clean it up. However, when keeping in mind API breakage and all the other associated issues therein, this is actually far more complex than one would be led to believe.

In the process of cleaning up the Metadata system, I had to address several glaring issues including memory bloat/performance issues. In addition, I had to implement a weak-reference system to prevent classloader leakage, but unfortunately that has the side effect of causing metadata in most cases to be cleared on a reload.

This is all leading up to a new feature I've been trying to get approved: Metadata Providers. The idea of metadata from the beginning was to faciliate inter-plugin data exchange, but the way it was done was actually quite limiting for a number of reasons. The discussion in that ticket got heated, and continued in another thread. At this point it's been at a stalemate, and no action has been taken since then.

I thought plugins had to provide the metadata, like that they stored it and connected to objects whent they're enabled.
That metadata was used for other plugins to easily access another plugins settings on objects.

Now why does this not persist on server restart? D: It would be so awesome if it did... It would remove all need for player config files (ie. essentials)! You could store the player metadata in the player.dat

Now why does this not persist on server restart? D: It would be so awesome if it did... It would remove all need for player config files (ie. essentials)! You could store the player metadata in the player.dat

Click to expand...

I disagree, somethings you want to be editable by simply modifying the file.

Can someone explain how to store and retrieve location metadata for a player?Example:
A player selects a block. Block location stored into player's metadata. Block location retrieved from player's metadata and stored in Location variable.
Storing it seems to be fine with:
player.setMetadata("selected-block-loc", new FixedMetadataValue(RaceTournaments.getInstance(), selectedBlockLoc));
But this line throws an error and says "FixedMetadataValue cannot be cast to Location".
selectedBlockLoc = (Location) player.getMetadata("end-block").get(0);

Side Question:
How should I store a list of players that are in multiple different race queues? I think server metadata would be the best option but I'm not quite sure how.

GetGoodKid Why are you placing it in "selected-block-loc" but retrieving "end-block" ?

Click to expand...

Oh my bad, I was trying to change variable names to make my code more readable. End-block is supposed to be "selected-block-loc".
It seems I fixed the issue though, by using .get(0).value();
What should I use in place of 0 index to make it specific to my plugin?

This looks really awesome! It's useful even for transferring data from place to place inside one plugin. IE removing the need for hashmaps and stuff. Will definitely implement this in my plugins. What would make this even better is if the data were persistent otherwise we have to store an entities UUID, save the metadata, then load it to the entities on startup.

You mention metadata being thread safe, but generally, there is little way to access objects that contain metadata in a thread safe manner, so what's the benefit of having 'thread safe metadata'

Click to expand...

The metadata API is thread safe because it was written that way, having "synchronized" on every method. While this may be thread-safe, it does cause locking on the -entire- store, so if the metadata was actually being used from many threads there would be a lot of waiting going on.

The "synchronized all methods" way is really a very old-school way of looking at concurrency, and really doesn't scale. In the interest of removing all those extraneous full-store locks, I have a pull request out to deal with that, https://github.com/Bukkit/Bukkit/pull/878 . However, I don't have time these days to work on pull requests for Bukkit, so if someone else wants to take this one over, it'd be great

The metadata API is thread safe because it was written that way, having "synchronized" on every method. While this may be thread-safe, it does cause locking on the -entire- store, so if the metadata was actually being used from many threads there would be a lot of waiting going on.

Click to expand...

Right, but the blockstore is not thread-safe, nor is the player list. So if you want to get data from a player/block you have to go through areas that need to be synchronized and have yet to be.