Services API: Economy

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

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

    petteyg359

    Why, exactly, would you and xZise go and start your own? Take the abandoned one, make a group on GitHub, invite whoever might work on it as a team, let people fork and push improvements, etc. Unless you just want to cause fracturing, like the original GM seemed intent upon...

    If you want something to be standard, make it the best. Don't arbitrarily name it as standard.
    (Potentially Really Bad) Analogue: Blu-Ray.
    If your economy plugin is the best, then people will use it, and they'll demand plugins that use it. Eventually, it'll become the de facto standard. The same applies for any other type of plugin.
     
  2. Offline

    Blarghedy

    I just used our names for a hypothetical example. The why of it doesn't matter. It happens. Look at how many permissions and economy plugins there are. Don't arbitrarily name it as standard? What do you think all of bukkit is? We named it standard because they do it best. The API won't die and need to be taken up again by someone else, only to die again, because it will be part of standard bukkit. It will never break.
    Again, what is an actual con to doing this?
     
  3. Offline

    petteyg359

    What is an actual benefit? If any plugin does things outside the "approved" API, you'll have to code around it anyway, so what's the point?
     
  4. Offline

    Blarghedy

    It's standardization. That's the point. That's the benefit. That's what I've said.
     
  5. Offline

    petteyg359

     
  6. Offline

    Blarghedy

    Fine, I'll say it another way: the benefits are the benefits I've already listed, including these.
     
  7. Offline

    DThielke

    This line of thinking assumes that there can only be one best for each category of plugins. However, not all plugins fit everyone's needs, even when multiple plugins share the same general purpose.

    Two economy plugins, for example, will likely share common features like adding to and withdrawing from accounts. However, economy plugin A might have features X, Y, Z, which our hypothetical user Bob has no use for. Instead, Bob wants to use economy plugin B because it has features I, J, K which suit his server's needs better. While both plugins offer different extra features, they share a similar core as they're both economy plugins. There is no best economy plugin in this case; users will choose between the two plugins based on their personal needs.

    A standard API in such a case becomes immensely useful for other plugins that want to interact with economy plugins A and B. If A and B share a common API, other plugin developers will only need to code for a single set of methods, rather than checking which economy plugin is active and using the methods specific to that plugin.
     
  8. Offline

    xZise

    But I would bet, that 95 % of the plugins need only the some calls listed above here somewhere. The other 5 % could do it the same way.

    And as DThielke already described, there are many economy plugins and there is no reason, why others should die their projects, only because of another plugins which will be used by more plugins. Normally there is a reason, why there are other economy plugins.

    And you as developer have to choose which plugins you want to support, and for me it is not relevant which economy/permissions plugin exactly the others use, as long as I have some basic methods. But I can't support all economy plugins without huge waste of time, to actually support them.

    Or the economy plugins uses an adapter to act like another economy plugin. But then the developer have to choose for which plugins he will write an adapter.

    And a APIHandler has a similar problem. Because when somebody writes his own version it will break the purpose of the APIHandler. Also only some people try to work with them, but no plugin supported it (like chicken or the egg problem). Also is this discussion here no competitor to the APIHandler, as this is discussion here want to describe an API where the APIHandler simply share it.

    About the standard itself: Maybe add the feature to allow simple “Non Player Wallets”. For example define, that the name is “<Type>.<Name>”, to support the BankAccount plugin (and all similar plugins). At the moment I couldn't be sure, that I have the player's wallet.

    Fabian
     
  9. Offline

    Etherous

    I'm thinking of making a set of plugins which will work together, but none would completely require the others. Among other things, these libraries would add a lot of financial and economic functionality missing from Minecraft. I plan to integrate this system with iConomy and other existing systems as required, and a standard web interface structure would be implemented for managing the various plugins. If anyone intends to create a standardized API for these systems, I would be happy to incorporate those standards into my plugins, otherwise I will be creating my own standards which others can use. My API will definitely be service-based, and modular components would function by providing services to other components. Though I haven't completely decided on all the functionality which would be provided, I can say that it would be much more in depth than providing wallet access. These are the four plugins I'm currently planning to implement:
    Corporations: Allows players to create and manage complete corporations, profits, employees, etc.
    Financial: Includes complete, complex, integrated financial system, including trading of stocks (Corporations), commodities, futures, options, currencies, etc.
    Law: Includes complete player-controlled legal system, including region customization (Nations), court systems, fines, prison, etc.
    Nations: Allows players to define countries, manage (Law)s, economy, currency (Financial), subregions, alliances, wars, etc.
    If anyone has input, ideas, or want to help with any of these plugins or creating a standard API for them, please contact me by email.
     
  10. Offline

    MichaelBurge

    I'm not entirely sure a standard Bukkit interface is even necessary; or even an API for systematically defining such interfaces.

    What's stopping someone from just writing a wrapper to all the different economy or permissions plugins themselves? If there's even one plugin author out there who's abstracted a generic economy interface for 5 different libraries, he can just release a new plugin API and now suddenly there isn't any hassle over supporting 5 different economy plugins for everyone else. Sure, if you want something really advanced that only iConomy supports, then you might have to get your hands dirty, but you'd have the same problem with any standard interface as well.

    I would argue similarly for permissions: If Permissions are a fundamental service yet there are a dozen different implementations, there must be *someone* out there who's already supporting them all; he could just release a wrapper plugin.

    You might argue that nobody's released such a standard API; but my main argument isn't that work doesn't have to be done somewhere, it's that the work of writing and releasing a wrapper is less than the work of defining a standard interface in Bukkit for defining standard interfaces, defining a standard interface for permissions/economy, getting a dozen development libraries to implement your interface, and convincing hundreds of plugin authors to use your service interface instead of the library itself.
     
  11. Offline

    xZise

    But if you have n economy plugins every plugin need n - 1 wrappers (in worst case). Or you have a really complex wrapper chain. Also the wrapper has to support all changes which the wrapped economy plugin does.

    Best example would be iConomy. With iConomy 5 it breaks almost everything. Now every plugin dev, which has a wrapper needs to rewrite this wrapper or add a new wrapper so they don't break support of iConomy 4.

    Sorry, but the plugin developer hasn't to support the standard API. Also if the standard API is finished it doesn't need to changed often. It is like in reallife. You have dozen of different power plugs and power socket. So for example if you are in Europe and travel to/from england you need to have an adapter. Now this isn't quite a big problem, as far as you travel not far away or you are in a big country.

    Another example would be a motherboard: Although there are lot of standards (USB, PCI, PCI-E, SATA …) there is a lot of things which doesn't need anybody. So the PS/2 plugs are for me non-sense. I need no PCI and IDE slot. But they are in the motherboard, because it want to support as much as possible. Now there is no new standard every month, but it is like here with plugins: If you want to support more than one economy system there are three ways:
    1. Write wrappers for economy plugin
    2. The plugin which uses the economy plugin have to write specific support for each economy plugin
    3. There is a standard which economy (using) plugins can follow.
    Now the disadvantages:
    1. You need in worst case n - 1 wrapper (n = number of economy plugins) to support all economy plugin. And these wrappers need to be maintained. All approximately (n - 1)² different wrappers by people which couldn't work on more reasonable plugins.
    2. Every plugin developer has to write its own specific support. So if every plugin supports n economy plugins there have to be n × m specific “wrappers” to support these economy plugins (m = number of economy using plugins).
    3. There has to be a standard which has to be maintained. Also the economy plugin developers which want to support this standard, have to do (maybe) a lot of work. But there is no duty that the developer has to do this. But could be reasonable if the standard is popular. If the standard doesn't cover the basics there is only 1. or 2. left.
    Advantages:
    1. In best case the economy plugin developers has to support only their own economy plugin.
    2. There is no really advantage.
    3. The economy plugin developers doesn't need to rewrite the standard support every day. Also could support the economy using plugin many plugins by default, if the plugin only need basics methods.
    If possible maybe create a poll, to see if a economy plugin developer will support his standard, or not, and if the plugin developer using the economy plugins will support his feature.

    And maybe you should add a “format” method.

    Fabian

    PS: A more interesting example would be the railway standards in europe (I don't know how it is managed in other countries): Every country in europe has it own security mechanism, gauge, overhead lines specifications (width, voltage, ac/dc), structure/loading gauge, it is terrific. Unfortunately there is only a German and French a article about this problem.
     
  12. Offline

    sk89q

    I currently handle permissions by wrapping around other plugins (WEPIF) but that's not a good solution because politics would get involved, a plugin may not be supported, and there will be forks, putting us back to square one. Plus, as with me, I have my own permissions plugin for my server, so this central wrapper would need to have a way to allow for that, which leads us back to a services framework.

    Which, by the way, already has been added to Bukkit. I have not yet added any interfaces yet.
     
  13. Offline

    xZise

    My suggestion would be two economy wrappers. One with integers (or longs) and one with doubles. And no “Account” management as some plugins doesn't support this (at least BOSEconomy and Essentials Economy). So it is easier to simply define the account's name every time, than emulate a Account management for those plugins which doesn't support this.

    Code:
    public interface EconomyDoubleAdapter {
    
        public boolean setBalance(String name, double balance);
        public double getDoubleBalance(String name, boolean createNew);
        public boolean createAccount(String name, double start);
        public boolean createAccount(String name);
    
        public boolean add(String name, double summand);
        public boolean multiply(String name, double factor);
    
    }
    And the int/long interface would be the same, with the difference that all doubles are integers or longs.

    For those which want to easily support both I would suggest following abstract class:

    Code:
    public abstract class EconomyAdapter implements EconomyDoubleAdapter, EconomyLongAdapter {
    
        public abstract boolean setBalance(String name, double balance);
        public boolean setBalance(String name, long balance) {
            return this.setBalance(name, (double) balance);
        }
    
        public abstract double getDoubleBalance(String name, boolean createNew);
        public long getLongBalance(String name, boolean createNew) {
            return Math.floor(this.getDoubleBalance(name, createNew));
        }
    
        public abstract boolean createAccount(String name, double start);
        public boolean createAccount(String name, long start) {
            return this.createAccount(name, (double) start);
        }
    
        public abstract boolean createAccount(String name);
    
        public boolean add(String name, double summand) {
            return this.setBalance(name, this.getDoubleBalance(name, true) + summand);
        }
        public boolean add(String name, long summand) {
            return this.add(name, (double) summand);
        }
    
        public boolean multiply(String name, double factor) {
            return this.setBalance(name, this.getDoubleBalance(name, true) * factor);
        }
        public boolean multiply(String name, double factor) {
            return this.multiply(name, (double) factor);
        }
    
    }
    Fabian
     
  14. Offline

    MichaelBurge

    I might have to reconsider my stance on just letting wrappers organically grow as needed, because I needed something a bit more like what a Bukkit service API would provide:
    http://forums.bukkit.org/threads/forcing-iconomy-to-be-zero-sum.16661/

    A proper event-handling system from Bukkit would make intercepting services to change them up a bit much easier. You might also intercept Permissions to, say, allow a user to have permission to use /money only when he's in a WorldGuard region defined as the city's bank. I'm sure you could come up with lots of other neat uses for interception.

    I still don't buy the standardization argument, because it doesn't actually save any work compared to other suggestions. But perhaps we could focus on what extra features a Bukkit services API might provide as infrastructure? Those would really make it attractive, I think.
     
  15. Offline

    xZise

    Okay I have no idea what you try to say with this. Do you want that a plugin get informed when the balance changes and transfer a negative change to another account? This is nothing what this API should do. You could write a plugin, talk to the economy plugin developers and maybe, they implement a event API on top of them. This API simply defines how other plugins could change balances.

    Go for it and implement a “neat” way. At the moment I would suggest to use the custom event to execute, but this is not relevant for this API.

    What are your other suggestion? Writing hundreds of wrappers and then a economy plugin breaks it API and the wrappers have to rewritten. Where is the work in here? Simply define the API and hopefully the economy developers implement them. But this should be easy, as all of this methods are already implemented. So they simply have the method to call the original methods.

    Fabian
     
  16. Offline

    Nijikokun

  17. Offline

    Blarghedy

    When should this be more fully implemented?
     
  18. Offline

    sk89q

    I'll have some time in a week or two.
     
  19. Offline

    Sammy

    Any news about the API sk89q ?
     
  20. Offline

    xZise

    Maybe I'm wrong, but if every plugin imports register there is a lot of overhead, and what is, if there is one with Register version A and one with version B? I don't know which one Java chooses.

    I have several problem, with two plugins having the same file. If I add one method in one file (and not in the other), it could be, that Java loads the older one. And everytime the plugin tries to access the new method it doesn't find this one.

    Maybe I'm wrong, and there are techniques to avoid this, but if there aren't any, I don't think that this will be a good solution.

    Especially every plugin developer has to manage to import the newest version of Register.

    Fabian
     
  21. Offline

    Nijikokun

    It's stable and it's not changing either, it currently has options to choose a preferred method or the first one it finds, also essentials utilizes it to hook into other ones incase it hooks into essentials then it's mapped to the correct one.

    And if every plugin imports register? No, it's directly included in the source, there is no overhead.
     
  22. Offline

    xZise

    So there will be no update? I mean your changelog isn't telling, that you does nothing. You fixed bugs and introduced features. Both changed the code. So if somebody used the Register version with the fixed bug, and somebody else not, it could be that both call the fixed methods or both call the buggy methods.

    The overhead is, that if there are 10 plugins with Register there is 10x the code of Register.

    Fabian
     
  23. Offline

    petteyg359

    Replace Register with Bukkit, or any other plugin, or even any other software ever written. The people who are too dumb and/or lazy to update anything won't update, and they'll have problems, and there's nothing that can be done to prevent that.

    Either you have really horrible coding style that involves copying and pasting external library code into your application and assume everyone else does the same, or you don't know how a computer actually runs programs. If you run 10 Windows programs, do you really think that you end up with 10 running copies of Windows?
     
  24. Offline

    xZise

    -.- There is a big difference between Bukkit and Register! Bukkit is to be supposed to be running only once. There is no “program” which runs Bukkit (in the same process) many times. Instead of Register! Each plugin has a build in Register (one (e.g. foo) has 1.5 and another (e.g. bar) for example 1.8). Now bar tries to use the new constructor with the preferred plugin. But Java loads the Register from foo. But foo's Register hasn't any constructor with a parameter. So Java will throw an exception, because it couldn't find the new constructor.

    Nope, but with 10 Windows programs. And if all of those 10 Windows programs have a Linux emulator, the Linux emulator runs 10 times. But I don't bother about the number of running programs (I think Java will load only one instance of Register), instead of the support: Every plugin developer using Register have to update Register for it's plugin and you have to download Register 10x.

    I mean a way better solution would be something like a library, which is distributed separately like the SQLite library. You don't have to download Register 10x, and could simply apply updates. Then you only have to make wise updates, and don't break the API all the time, and the plugin developers don't have to “update” their plugin always when Register was changed. The server administrator simply replaces the Register library and we are done.

    And with “wise” updates I mean: Add features all the time (won't break anything), and if you remove a feature make it clear. For example by using a version number where the first number identifies that this could break something, the second is only a feature add, and the third a bug fix. For example if a plugin supports 1.2.0 it means, that it will support 1.2.1 or 1.3.0. But not 1.1.0 (the feature isn't introduced) and maybe not 2.0.0 (a needed feature was removed/changed).

    Fabian
     
  25. Offline

    Blarghedy

    No. This is not how programs work. "Java" isn't this big entity that sees everything that your program attempts to load. Java loads bukkit. Bukkit loads, say, plugin 1. Plugin 1 loads Register 1.5. Bukkit loads plugin 2. Plugin 2 loads Register 2.5. This is, of course, if it was built with it and so on and so forth. Register is not a separate program. It is a library, just like any other Java class file.
     
  26. Offline

    xZise

    Okay, no. If they are in the same package and would override, it won't working. I have several problems where I changed one file in one plugin. The other plugin has an older version of the file. Now the first plugin couldn't use the older version. And maybe other way around. Now sometimes, it is loading the newer and sometimes the older file. And both plugin are accessing the same (!) file.

    Check out my CrashTest example. They share one java file (de.xzise.Shared) which I modified or "updated" for C2. So C1 and C2 are using different Shared. Your hypothesis says, no problem at all, but I tested it, and it crashed, because it couldn't find both methods. It finds only one because it loads only one Shared instance.

    And if you mean: The plugin user has to update, why don't make a library of register. The administrators could easily update Register, and don't have to (passive) download Register every time. The plugin developer don't have to bother with updating/importing Register. Only Nijikokun has to release a jar file for each update.

    Fabian
     

    Attached Files:

  27. Offline

    przerwap

    Remind me again but didn't this begin as a discussion of ease-of-access and storing plugin data inside the Player class?
     
  28. Offline

    petteyg359

    What do you think it is? You're accusing the cat of eating the canary because you haven't bothered to look up and see it shitting in your hair from the cabinet above you.
    That's called "PEBKAC". If the user (in the above case, you) is trying to use conflicting versions at the same time, they're going to get errors as a reward for their idiocy. Do you have any valid arguments?
     
  29. Offline

    xZise

    As I said above: Release a separated library which isn't included in the plugins. Then the plugins uses the library and the server admin could update easily. Okay my example won't work with the library style, but normally you add functionality or fixes bugs. So in my example the C2 Shared file would contains the “getOne()” method. I removed it, because now it will break either way, if the C2 Shared have getOne() it could be, that the C2's Shared will be loaded, and it works fine.

    Did you even read my post(s)? Every plugin developer will be forced to update his plugin if Register is releasing a update – for none sense. Simply because another plugin could use new functionality and Java loads the wrong version of Register. The only (!) disadvantage with using the library is, that somebody has to release a Register library.

    The disadvantage in the system it is working like now is, that you (indirectly) download Register every time, so everybody has to build this into it's jar, has to upload it, and everybody has to download it.
    Also every plugin developer has to track updates and is forced to update the plugin.

    Fabian
     
  30. Offline

    przerwap

    Than don't use another developer's shit to make your own plugin work.

    ^
     
Thread Status:
Not open for further replies.

Share This Page