Services API: Economy

Discussion in 'Plugin Development' started by sk89q, Apr 12, 2011.

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

    sk89q

    Something Bukkit needs is an API for plugins to register "services" in order for interoperability between plugins to be maximized. For example, if your plugin needs to get a player's wallet (in cash or points) on hand (for economy), there should be an easy way to do it without querying for 20 different economy plugins. Therefore, here has to be as standard for various services that may be needed that is both complete and extendable. Because not all plugins may implement all features, the services system MUST also have an understanding of "capabilities" so that plugins can declare what is supported. This thread is for discussion of a services API for economy services.

    We can start off with this:
    • double getWallet(Player player)
    • void setWallet(Player player, double amt)
    Capabilities:
    • HAS_WALLET

    (No name is final.)

    Suggest both methods and capabilities in this thread.
     
    zachoooo and Jadedwolf like this.
  2. Offline

    Kainzo

    All for an API with economies.
     
  3. Offline

    DThielke

    I suggest a more general version of your two methods that accept a name, rather than a player as an argument.
    • double getWallet(String account)
    • void setWallet(String account, double amt)
    These allow for accounts that are associated not just to individual players, but to organizations, server services and a number of other things that someone more creative than me can come up with. These methods don't necessarily need to replace yours, but I feel they're important to have.
     
  4. Offline

    narrowtux

    Can't this go into Persistence when it's finally finished? Like, an over-plugin property system?
    So the developer of an API can register a variable in this property system and it's purpose and this property is being accessible over a string. For example:
    Variant getProperty(String type, String argument);
    Then, the server checks if the type is already registered and returns the value for the argument. Variant is a variable datatype. Look at the Qt documentation for the QVariant Class.

    We have to do something with registering a type because otherwise, we'd had multiple types for the same thing soon, e.g. a wallet.

    When we standardise the types, the plugin devs have no more problems with all the different incompatible Economy-APIs
     
  5. Offline

    sk89q

    That could work.

    Though there would need to be something to differentiate between a player and some other account, because plugins would just simply give the name of the player in most cases I imagine.

    I don't believe in accessing data directly like that, first, because that prevents plugins from doing pre-processing on the raw data; second, because it would allow other plugins to meddle in the data of another plugin (not a terribly good idea); and third, because it assumes that it would be in persistence to begin with. Plugins are not going to all store data in the same way as well, so it would be silly to attempt to conform plugins to that.
     
  6. Offline

    DThielke

    I don't disagree, but what would the purpose of differentiating the two be?
     
  7. Offline

    Blarghedy

    Are you limiting this to economies, or is this something you want to expand? I've been thinking lately about a similar thing for warp plugins, because they're so inefficient. Would this service system type have a "Service: x, description: y" type thing? If so, I'm all for that.
     
  8. Offline

    rakiru

    A player's name could be the same as some other random account's name.
     
  9. Offline

    Crash

    Perhaps this for setting up/removing an account for a player or group :
    void createWallet(String account, double startamt)
    void deleteWallet(String account)

    For interest rate(if it is added) :

    double getInterest()

    Will this be kept simple or is it going to be more complex ?
     
  10. Offline

    Mixcoatl

    Incidentally, not every economy system out there restricts players to a single denomination of currency. It might be nice if we had something like:
    Code:
    interface Wallet {
        double getCurrency(); // use default currency.
        double getCurrency(String currency);
        void setCurrency(double amount); // use default currency.
        void setCurrency(String currency, double amount);
    }
    // Elsewhere.
    interface WalletProvider {
        Wallet getWallet(String context);
    }
     
  11. Offline

    sk89q

    This will be applied to a host of things such as warps, homes, friends lists, etc. I'm just starting with economy for now. Types of services can be added at runtime if needed.

    I'll add those things.

    This can get pretty complex because plugins will be able to declare "capabilities," allowing for a gradient of support for more advanced features.

    Where do you suppose "currency" could come from? Would the user specify it?
     
  12. Offline

    aranian

    my take on this:
    bukkit would provide the basic interface for the service provided (simple economy in this example)
    Code:
    public interface Wallet {
      public long getAmount();
      public void setAmount();
    }
    
    public interface WalletManager {
      public Wallet getWallet(Player player)
    }
    currency systems could then implement these interfaces and add to it, e.g. calculating interest for each wallet at certain intervals.
    to make this accessible to other plugins regardless of the system used currency systems would inject a WalletManager into the server. If another plugin tries to insert a different WalletManager an error should be raised.

    a plugin that wants to use wallets can then ask the server for the WalletManager instance of this server and find the Wallet of a player and use the methods of the interface to store money.
    if a currency system provides more methods than the basic ones and a plugin might want to use them it should add the currency system as a dependency and cast to the specific class.
     
  13. Offline

    Mixcoatl

    Someone would have to specify something, somehow. The currency parameter in the interface is really intended to be some sort of opaque identifier the implementation can use to determine which denomination of currency is intended.
     
  14. Offline

    Nijikokun

    This has already been done, please stop re-creating the wheel and use the search feature; No I am not lying, its in the WIP / Resources somewhere.
     
  15. Offline

    xZise

    Do you mean APIHandler.

    A “type” label? So define well known types like “player”, “group” and plugin specific types.

    Fabian
     
  16. Offline

    ZachBora

    I don't really like the idea of a "set" method when we're talking about money. There is no bank system out there working this way, it's just "add" and "remove".

    You could be calling "get" adding money then another action changes your amount and the plugin uses "set" and now the amount is wrong.

    The only reason to use a "set" would be to make an account 0 or to start up an account with an initial amount.
     
  17. Offline

    Mixcoatl

    I like this. It makes sense in the context of its domain. I would, then, posit three methods: deposit, getBalance, and withdraw.
     
  18. Offline

    xZise

    And a forth “setBalance”. I mean you could add a abstract class, which will only have one method left and let the others redirect to it. So if somebody need the interface it is possible to use this, and other developers could use the abstract class. But the plugin developer which uses the economy plugin should use the interface.

    Fabian
     
  19. Offline

    sk89q

    Setting can be one of those "capabilities" if you need it, but it can be something that not everything provides.

    I couldn't care less. This is something that needs to be a part of Bukkit, and it has been discussed long before any other plugin, back in December.
     
  20. Offline

    Raphfrk

    What you want is something like

    double credit(double amount)

    This would attempt to deposit amount and return how much was actually deposited.

    double debit(double amount)

    This would attempt to withdraw the amount and return how much was actually withdrawn.

    Also, there should be a method to transfer between two wallets.

    double transfer(Wallet target, double amount)

    All amounts are just requests. The back-end can decide to send less.

    It might be worth having an "atomic" flag. If this is set, either the transaction happens fully or fails completely.
     
  21. Offline

    petteyg359

    You really think that an economy should be a part of the core server?
     
  22. Offline

    Blarghedy

    No, that's not the point of this. This isn't about economies. This is about services in general having a decent and useful API.
     
  23. Offline

    xZise

    Jep it would be nice, if there is an general API for plugins which are for plugins. Okay Permissions should some time in the core, but such things as economy could easily done by plugins but it would be nice if Bukkit allows me to share the APIs easily.

    Also I think that a currency shouldn't store as a double. For me I hate the rounding errors and possible wrong comparisons. Because most currencies have a base currency (like Euro/Dollar…) and a divisor (Cents…). So for example store the actual balance as cents and divide by 100 so you could show the balance as Euro/Dollar etc. The int allows (2³¹-1)/100 = 21 474 836.5 €/$. And if this isn't enough a long should be big enough.

    Fabian
     
  24. Offline

    petteyg359

    That's my point. If you want <insert-economy-or-something-here> plugins to all use X interface/API with X features, then convince all <insert-economy-or-something-here> developers to merge into a single plugin. If there's going to be a prescribed interface/API for things that aren't even part of the core server, then you might as well ditch the plugin architecture and have "approved" "plugins" built-in.
     
  25. Offline

    Blarghedy

    This wouldn't require the use of the interface, though. It would just make it easier to make, say, an economy plugin, which would be useless without another plugin taking advantage of it. Even if the economy plugin does use the standard functions (say, "getCurrentMoney()), it could still use its own as well. It would just make it easier to have any standard at all. I know don't want to deal with 20 different APIs. I just want to use one.
    Same with, say, home. I'll have a plugin that sets home to where I sleep. Then I have a plugin that has a command, say /tohome sk89q, that lets me warp to sk89q's home instead of my own. How would these two plugins interact? There are a dozen plugins that set homes. If a home is standardized, then it's doable. Until then, it's really not, unless you like dealing with and keeping up with a dozen different plugins that don't actually have anything to do with you.

    EDIT: Sorry I babbled a bit. I'm operating on no sleep today.
     
  26. Offline

    petteyg359

    So ask the /home plugin developer to add a getHome() function so your toHome plugin can access it, or ask them add toHome() directly. If "a dozen plugins don't actually have anything to do with you", then what on Earth do you need them to have a standard API for, when they "don't have anything to do with you"?
     
  27. Offline

    Blarghedy

    Sorry, I was unclear. It's not that they have nothing to do with you, it's that you shouldn't even need to know they exist. As it currently stands, my 'tohome' plugin would need to have information about every single home plugin in order to be fully functional. With this services api, my tohome plugin would be able to just query the system, see what plugin has home, and use the standard (because of the api) getHome() function.
     
    GatsbyTheGreat likes this.
  28. Offline

    xZise

    @petteyg359: Maybe I get you wrong, but why shouldn't be this problem be solved with the bukkit team. So everybody could register interfaces like plugins and allow to share them easily. At the moment I only could support iConomy in my plugins. Now I could add support for the hundred others economy plugins, or hope that other economy plugin developer also write a second plugin, which implement a adapter and simulate to be iConomy. Or I support only iConomy. But there are users with other economy systems so the system at the moment is awfully incompatible.

    Mostly the plugin developers only need to get an account and change their balance. And maybe a “format” function. If now a developer support more than this and another plugins need this special abilities this plugin can work like now, but if you only need basic capabilities a basic API should do it.

    Also who is deciding which is supported and which not? I mean the developer of iConomy could change all method calls and every plugin depending/simulating it has to change the calls.

    Fabian

    PS: I haven't followed the progress of Raphfrk's pull request, but he already suggested a interface system like I described in the first paragraph.
     
  29. Offline

    petteyg359

    As posted earlier, we already have such functionality in a plugin (APIHandler). You just need to get somebody to update and maintain it, and convince people to use it.
     
  30. Offline

    Blarghedy

    Alright, there's that API. Now I'm going to make my own API handler and xZise here is going to make his own as well. Now it's like with economy: which do you support? Why? Oh, wait, one of them doesn't support Permissions. However, that's the only one that has, say, warp support. Oh darn.
    It's so much easier to have a standard. The standard doesn't have to be followed, but it would be easier for everyone if it were. If a standard exists, there will be no "convincing people to use it". People just will, and people will end up gravitating toward those plugins which do. What about a standard API would actually be bad?
     
Thread Status:
Not open for further replies.

Share This Page