|
Welcome to the BukkitWiki!
|
Common Coding Etiquette
|
This page has been marked for deletion.
|
|
Working on it...
|
Contents |
Introduction
Use the API: http://jd.bukkit.org/apidocs/
also the index: http://jd.bukkit.org/apidocs/index-all.html
Search on the resource forum: http://forums.bukkit.org/forums/resources.60/
and the Plugin Development forum: http://forums.bukkit.org/forums/plugin-development.5/
or use google ;)
Storage - How to store primitive data and objects
It is important to store stuff to reduce the calculation time and access them faster, e.g. if you change a fixed number of sign:
import java.util.ArrayList; import org.bukkit.block.Sign; public class SignStorageBad { private ArrayList<Sign> signsStorage; public void makeSomethingWithSigns() { loadSigns(); for (int i = 0; i < this.signsStorage.size(); i++) { Sign tmpSign = this.signsStorage.get(i); tmpSign.setLine(0, "first line"); tmpSign.setLine(1, "second line"); } } private void loadSigns() { if (this.signsStorage == null) { loadSignsFromSomewhere(); } } private void loadSignsFromSomewhere() { // get the coordinates of Signs from somewhere // and add them to the storage } }
A List, e.g. ArrayList has a dynamic size, but need a longer time to read a value from a special index, better use an Array:
import org.bukkit.block.Sign; public class SingStorageBetter { private Sign[] signsStorage; public void makeSomethingWithSigns() { loadSigns(); for (int i = 0; i < this.signsStorage.length; i++) { Sign tmpSign = this.signsStorage[i]; tmpSign.setLine(0, "first line"); tmpSign.setLine(1, "second line"); } } private void loadSigns() { if (this.signsStorage == null) { loadSignsFromSomewhere(); } } private void loadSignsFromSomewhere() { // get the coordinates of Signs from somewhere // and add them to the storage } }
If your signs has an identifier (a unique name, or unique id), and you only want to change a specific sign, maybe a HashMap is a better choice:
import java.util.HashMap; import org.bukkit.block.Sign; public class SignStorageHashMap { private HashMap<String, Sign> signsStorage; public SignStorageHashMap() { this.signsStorage = new HashMap<String, Sign>(); } public void makeSomethingWithSignsXY(String identifier) { loadSigns(); Sign tmpSign = this.signsStorage.get(identifier); tmpSign.setLine(0, "first line"); tmpSign.setLine(1, "second line"); } private void loadSigns() { if (this.signsStorage == null) { loadSingsFromSomewhere(); } } private void loadSingsFromSomewhere() { // get the coordinates of Sings from somewhere // and add them to the storage } }
SaveBlocks - How to save blocks and restore them
A Block is more than only the Material (GLASS, IRON, ...). To save a Block correctly use a BlockState.
What is a block state:
"A BlockState is basically just what it says: a block's state at the point of time when it is created. Unlike the regular Block instance, it won't automatically update/change when the block itself changes and vice versa (the block won't update when the BlockState changes).
The main uses I can think of right now for BlockStates: Storing a snapshot of blocks to use it later - e.g. you set an area of blocks to something for your plugin, but you want to reset it to the original blocks later. Instead of manually storing the previous blockIDs/data (and TileEntity data like chest contents, sign text, etc.) you just store BlockState's and then update() them.
Getting access to enhanced block-specific methods for TileEntities (e.g. Signs, Chests, Furnaces, etc.) - common example is setting the contents of a Sign. The class "Sign" extends BlockState, so getting the BlockState, setting the lines, and then updating the sign is the way to go." ( from: Bone008 )
TODO: make an example.
Commands
How can I handle commands?
needed?
or is
and
http://forums.bukkit.org/threads/tut-how-to-create-the-i-item-command-using-hashmaps.45378/
enough?
You shouldn't just return if the sender is not a instance of Player
Your plugins should not just instantly check if it's a player and return without bothering to process it if it is not. This isn't very nice to the user, it's not very nice to other plugins, and it degrades the overall quality of the plugin. This should be done depending on the command they enter and its usage.
For example:
- A command such as /kill should not just return if the sender is not a player.
- A command such as /sethome requires the location of a player entity so it does make sense to restrict it to players.
Warning: Don't just do this, if it makes sense for you command can be used from the console!
@Override public boolean onCommand(CommandSender cs, Command cmd, String alias, String[] args) { if(cs instanceof Player) { //Command magic goes here } else { cs.sendMessage("Sorry, but this command can only be used in-game"); } return true; }
Basically, if the command you are writing will work from the console and does not require a call like player.getLocation() or something, you can feel free to make sure it's a player first, and disallow consoles for obvious reasons. Otherwise, make it work from the console!
Events - How to react on events, what is special on BUKKIT event managment?
- use ignorecancel Anotation
- you can register Sub-Events
- Unregister Listener
- Action comes before event
TODO
Discussion: BukkitForum
Loggers
Instead of creating your own loggers, use the logger supplied by bukkit. Loggers all have names, and should have a unique name, never create one named "Minecraft". Use JavaPlugin's getLogger method instead of creating your own logger from the logger factory.
File Locations
Your plugin's data folder need not always reside in the plugins directory on a server. Use JavaPlugin's getDataFolder method instead of hard coding your file paths to the plugin directory.