Services API Intro

Discussion in 'Plugin Development' started by zml2008, Jul 19, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    zml2008

    Bukkit has a little-known Services API accessible via Server.getServicesManager(). It allows multiple plugins to register their support for cross-plugin services, intended to greatly reduce the amount of APIs plugin developers have to write support for. It was added quite a while ago by sk89q, but has not been used frequently due to a lack of plugin developers who know about, and how to use it. Therefore, I present this intro to the Services API.

    Concepts
    The Services API depends heavily upon the concepts of services and providers. A service is usually an interface that providers can implement. Services are only registered with the services manager alongside providers. A provider is usually an implementation of a service interface, though separation is not necessary. The Services API was written for multiple plugins implementing a single interface, though a plugin can register the same class as both a service and a provider.

    Registration
    Code:
    public <T> void register(Class<T> service, T provider, Plugin plugin,
                ServicePriority priority);
    
    Plugins register services with the server's ServicesManager. PEX registers its PermissionManager class with the following:
    Code:
    this.getServer().getServicesManager().register(PermissionManager.class, 
    this.permissionsManager, this, ServicePriority.Normal);
    
    This registers PEX as a provider for the PermissionsManager service with the priority Normal. Priorities are one of the perks of using the Services API. When a plugin asks the services manager for a service provider, it will by default return the highest priority registered service for the plugin to use. This reduces the chance of conflict between plugins providing a service.

    Lookup
    Code:
    public <T> T load(Class<T> service);
    
    A plugin wishing to use a registered service in most cases should use this method to get a registration. My plugin that uses the PEX PermissionManager service to get the prefixes and suffixes of players uses the following code:
    Code:
    PermissionManager permissions = this.getServer().getServicesManager().load(PermissionManager.class);
    String pre = permissions.getUser(player).getPrefix().replaceAll("(&([a-f0-9A-F]))", "\u00A7$2");
    String suf = permissions.getUser(player).getSuffix().replaceAll("(&([a-f0-9A-F]))", "\u00A7$2");
    
    The plugin then has access to the highest priority PermissionsManager registered with the PermissionsManager service.

    Writing services and providers
    Permissions Service Example (open)

    import org.bukkit.World;
    import org.bukkit.entity.Player;

    public interface Permissions {

    public boolean hasPermission(Player player, String permission);

    public boolean hasPermission(Player player, World world, String permission);

    public Player[] getPlayersWithPermission(String permission);

    public Player[] getPlayersWithPermission(World world, String permission);

    public boolean inGroup(Player player, String group);

    public boolean inGroup(Player player, World world, String group);

    public String[] getGroups(Player player);

    public String[] getGroups(Player player, World world);

    }

    Writing services for the services api is very simple, which wile hopefully help to counteract the current severe lack of services for the API. Any interface and its implementation can be registered with the API and fetched by other plugins. A provider can provide multiple services with different priorities.

    This introduction hopefully has all the information you'll need to get started developing plugins using the Services API. The Services API is a great way to manage many plugins providing a similar function without having to individually write support for each plugin providing a function. The API also provides an easy way for plugins to interface with other plugins.

    Plugins known to be using the Services API
    • Plugin Name by Author - Interface implemented
    • PermissionsEx by t3hk0d3 - PermissionManager
    • Vault by Cereal - Economy and Permission
     
    Cloaking_Ocean likes this.
  2. Offline

    MiracleM4n

  3. You're right and nice to know:p

    could you maybe add a fully working example plugin??
    (and maybe a 2nd that interact with the first one)

    I really want to use it and the easiest way to learn how to use it is to work with an example, right?
     
  4. Offline

    t3hk0d3

    Request sticky thread
     
  5. Offline

    Celtic Minstrel

    I like the general idea of this, but it doesn't sound like it would be terribly useful unless either a) Bukkit includes a repository of useful interfaces (with no implementations) or b) a single plugin exists to provide all or most of the useful interfaces. Otherwise every service would require one plugin for the interface and one plugin for the implementation, practically doubling the number of plugins you install (though yes, in some cases those two plugins could be the same). Unless I'm missing something here?
     
    Splitrox likes this.
  6. Offline

    EdGruberman

    I just stumbled across this and I'm curious if Celtic Minstrel is right or not. Unless Bukkit centrally manages the service definitions, wouldn't this just cause people to define new services if the existing service didn't match their desired provider? In effect, I can't see how this consolidates unless plugin developers agree to a service definition but isn't that the root problem, that plugin devs can't agree?
     
  7. Offline

    Celtic Minstrel

    I think Vault exists to satisfy b), but the trouble there is that it ends up providing an implementation wrapper for various plugins in addition to defining the interface, so while it's a good idea it kinda hasn't worked out.
     
  8. Offline

    damospiderman

    It works well with Vault to provide an interface to various different economy and permissions plugins without the plugin creator specifically needing to know the version of the economy plugin etc.
     
  9. Offline

    Celtic Minstrel

    Yes, Vault does its job well enough, but as a repository of services that other plugins can implement it hasn't really been successful.
     
Thread Status:
Not open for further replies.

Share This Page