[ECON] DynamicMarket V0.6.0 - Versatile Shop Plugin [953]

Discussion in 'Inactive/Unsupported Plugins' started by GoalieGuy6, Jul 3, 2011.

  1. Offline

    GoalieGuy6

    DynamicMarket - Dynamic Global Shop Plugin
    Download V0.6.0 (JAR | Source on GitHub)

    Current version: 0.6.0
    Tested against: CraftBukkit build #953

    JAR Mirror (Version 0.6.0)
    Older Versions


    Note: Upon first run the plugin will attempt to convert your database in order to add decimal support to item prices. I was unable to test the conversion code too extensively so if you run into any errors with this please post your server log so I can take a look.

    Most of this was copied from the original thread found here. This is the first plugin I have ever worked on and also the first Java project I have worked on, so I am sure there is a lot that I could've done better. For now I haven't done much more than add a few small features and fix a couple bugs. If you have any requests or experience any bugs/errors please let me know and I'll see what I can do.

    Some of the information below is outdated, I am working on updating the post.

    Requirements:
    Read this before proceeding

    READ THIS (open)
    This plugin has a great deal of flexibility, but the price of more flexibility is more command options to control that flexibility. Computers just aren't very psychic.

    While in-game help exists for commands, the output from /shop help (<topic>) is intended to be a quick reference, not exhaustive documentation. Full instructions simply won't fit on the MineCraft client's tiny text display.

    You should read and understand the following sections before installing this plugin and setting up your shop. If not, you should at least read and understand the following sections while you are setting up your shop items.


    The big feature: Dynamic pricing. Items can be set to increase in price as they are purchased from the shop, and decrease in price as they are sold back, simulating open market conditions. The initial prices of items are just considered a starting point - user transactions will eventually adjust an item's price to a near-ideal level, based on actual value vs. rarity.

    However, as of 0.4.5, the configuration fields are now flexible enough to allow a range of behaviours, from fixed pricing with no stock limits, to fully-dynamic pricing with finite stock levels.

    This is by no means "complete" in the sense of "finished adding features", but it is complete enough to be functional and usable.

    Current Features (open)
    New & Current Features:
    • Buying and selling of items:
      • Item prices can now have decimals in them!
      • Checks if a player has enough space to hold items before purchasing!
      • Item prices can be set to dynamically adjust according to supply and demand. This is highly adjustable, including the rate of price increase/decrease per transaction, optional hard overstock/understock limits, price ceilings/floors, etc. Leaving all the extra features turned off makes an item's price fixed and always-in-stock, like a basic "flat rate" shop.
      • Subtypes of items are fully supported.
      • List of items in the shop is broken into pages, accessible by number.
        • Partial-name searching! "/shop list wood" shows everything with "wood" in the name.
      • Item names for buy/sell/info also use partial substring matches.
      • A dynamically-priced item might cost more for 10 items than the cost of 1 item multiplied by 10, due to stock depletion. So, the "/shop <id>" command now takes an optional ":<count>" parameter, so you can get a quote for the actual buy/sell price of larger numbers of items.
    • Administration:
      • Set OPs to have all admin permissions in the config!
      • Shop items are edited via a "tag" system, so you don't have to re-enter every field for each small change. Plus there's a few utility tags which do other things to an item's record...
      • Item names are now editable, and will persist (independent of items.db) until the item's record is deleted.
        • This also makes items.db a convenience instead of a necessity, since items can be added by ID and then immediately renamed.
      • A "Default" item exists in the shop, which cannot be bought or sold, but serves as the base data for any new items you add to the shop. Any tags not supplied when you add an item will be copied from whatever you put into "Default".
      • Basic sanity-checking on input data has been added. Also, adjusting an item's bundle-size will rescale its price automatically.
      • Items can be set to be purchasable but not sellable, or vice versa. (Set either price to -1 to disable that transaction type for that item.)
        • Tags like "canbuy:n" and "nosell" can now be used.
      • An extended in-game help system. "/shop help" lists available commands and help topics. "/shop help <topic>" gives help on a shop command or other shop-related topic listed in the main help.
      • The list of commands displayed is filtered by the user's current permission level.
      • Shortcuts for all commands (except for database reset).
      • All commands except for "/shop buy" and "/shop sell" can be accessed through the Bukkit console. No need to log in to add or update items!
      • Access to the entire shop is now restrictable by permission.
      • Highly informative error messages, to help reveal why your database exploded. (Which really shouldn't happen, but you never know...)
      • The shop DB can now be exported to a .csv file, edited in your favorite spreadsheet, and re-imported back into the database, making large-scale changes easier.
      • The revenue/cost of transactions can now be transferred to another account. With the basic plugin, this can be an admin's iConomy account, or a dummy "GovernmentBank" account. (Don't use that name, or some bright spark will register that username and exploit you.) With a wrapper plugin, this can be set to link a shop's funds directly to an owning player's iConomy balance.
      • Transaction logging to a comma-delimited file, ready to import into a spreadsheet for nefarious financial analysis!
    Market Mechanics (open)
    Quick Market Mechanics Description:

    • Instead of a "buy price" and a "sell price", items now have a "base price" and a "sales tax". The "buy price" is based on the base price (adjusted by stock, if set to do so), and the "sell price" is based on (<buy price> - <sales tax%>). So if the sales tax is set to 25, then an item's selling price will be 75% of its purchase price. (The sales tax is entered as a number from 0 to 100, representing 0% to 100% tax.)
      • Using the old "/shop add <id> <buyprice> <sellprice>" format still works - the plugin just calculates the base price and sales tax, so that the buying and selling prices come out right.
    • Shop items have a "stock level", which is not necessarily a literal count of items in stock. By default, the stock level is considered an offset from baseline, rather than an absolute count.
      • Items with stock near zero are considered to be in "average" supply, and will be priced at their base price.
      • Items with a positive stock are considered "in surplus", and will be priced below their base price.
      • Items with a negative stock are considered "understocked", and will be priced above their base price.
      • This interpretation of stock levels can be made to behave like literal counted stock, by setting an item's StockFloor to zero, which prohibits negative stock.
    • Items have a "volatility", which indicates how quickly the price changes based on changes in stock level. It represents the percent increase in an item's price per item purchased, multiplied by 10000. V=1 (the lowest level) means that 100 items would have to be purchased to raise the price by 1%. V=10000 (the highest level) means that 1 item purchased would raise the price by 100% (doubling the price). (More examples in tags.txt)
      • There is also "inverse volatility", which represents the number of items needed to be bought in order to double the buying price (or halve it, if selling). This is more convenient for some people's mindsets, and is converted into volatility when entered.
    • The "sell price" is actually calculated from the buy price at the current stock level + 1, rather than the current stock level. This is to prevent gaining endless money by buying an item (driving the price up) then immediately selling it back (dropping the price) - if <sales tax> = 0, then buying-then-selling like this produces zero net gain/loss (as it should).
    • The tag presets "fixed", "float", "finite", and "flat" allow you to quickly set up common options. If used with the "Default" item before adding items to your shop, this will allow you to set the overall behaviour of the shop easily. See Tag Reference for further details.
    Commands (open)
    Commands:


    <Angle Brackets> denote parameters.
    (Round Brackets) denote optional sections.
    The brackets themselves are not part of the command; they are just used to describe syntax. Brackets should not be typed.
    If executing shop commands through the Bukkit console, leave off the initial slash.

    /shop - Shows the main help page. Lists commands and shortcuts.
    /shop help - Ditto.
    /shop help <topic> - Shows help on the given command or subject.
    /shop help tag <tagName> - Shows help on the given item tag.
    /shop <id>( :<count>) - Shows current buy/sell information on the given item.
    <id> can be an item name or a type number with an optional subtype:
    <id> = <itemName> | <itemID> | <itemID>,<subtypeID> | Default
    If <count> is used, shows the total price for the given number of items/bundles.
    /shop list (<partname>) (<pageNum>) - Lists a page of items in the shop. Default page = 1.
    If <partname> is used, lists only items with <partname> as part of their name.
    /shop buy <id>( :<quantity>) - Purchases an item. Default quantity is 1 bundle.
    /shop sell <id>( :<quantity>) - Sells an item. Default quantity is 1 bundle.
    /shop add <id>( :<bundleSize>) (<buyPrice> (<sellPrice>)) <tagList> - Adds an item to the shop list.
    <buyPrice> and <sellPrice> are accepted for convenience, and are internally converted to BasePrice and SalesTax.
    Unused tags will have their data copied from the Default item.
    Transactions will be in multiples of <bundleSize>. Default quantity is 1 item per bundle (unless overriden with the Default record)
    /shop info <id> - Shows much more detailed information about an item in the shop, such as stock level, volatility, etc.
    /shop update <id>( :<bundleSize>) (<buyPrice> (<sellPrice>)) <tagList> - Edits an item's shop data record.
    Data is first copied from the old record, then tags are applied in order of entry.
    <id> can be "all", applying changes to all items in the shop list.
    /shop remove <id> - Removes an item from the shop list.
    /shop reload - Reboots the plugin, reloading the configuration file and items.db.
    /shop reset - Deletes and recreates the shop database from scratch. Asks for an extra confirmation before doing so.
    /shop exportdb - Exports the shop database to a .csv file. The name and location are configured in SimpleMarket.settings. (Default: Plugins/DynamicMarket/shopDB.csv)
    /shop importdb - Imports a .csv file into the shop database. Same file location as used by the exportdb command. Note that the previous contents of the database are NOT cleared out before importing, so you may want to do a "/shop reset" before importing. The file's format MUST match the format of the exported file (except for quote marks, which are stripped out on import).
    Permission Nodes (open)
    Permission Nodes:

    'dynamicmarket.access' : Grants basic access to the root /shop command.
    'dynamicmarket.buy' : Grants purchase rights.
    'dynamicmarket.sell' : Grants selling rights.
    'dynamicmarket.items.add' : Grants the ability to add new items to the shop.
    'dynamicmarket.items.update' : Grants the ability to edit items in the shop.
    'dynamicmarket.items.remove' : Grants the ability to remove items from the shop.
    'dynamicmarket.admin.reload' : Grants the ability to reload the plugin's config and db.
    'dynamicmarket.admin.reset' : Grants the ability to reset the shop's database.
    'dynamicmarket.admin.db' : Grants the ability to export and import the shop's database using .csv files.
    Installation/Setup (open)
    Installation/Setup:
    Step 1) Make sure you have all the required plugins/dependencies
    Step 2) Copy DynamicMarket.jar into your Plugins/ folder.
    Step 3) Add the permissions if you are using a permission plugin.
    Step 4) (Re)Start your MineCraft server. Errors may be thrown to the console, but the file Plugins/DynamicMarket/DynamicMarket.settings should be created.
    Step 5) Edit DynamicMarket.settings to suit your needs.
    Step 6) Use "shop reload" from the console to load the edited config file.
    Step 7) Use /shop add to fill the market with tasty blocks at scandalous prices.

    Note: You WILL want to use "/shop update default" to set up some sensible default values for the items you will be adding, so you don't have to do so much typing for every item. (Or at least inspect the Default entry, to be sure you agree with it.) If you want to make all of the items in the shop use dynamic pricing, set up the parameters in the Default item FIRST, so you don't have to go back and modify 100+ items to support variable pricing.
    Configuration (open)
    Configuration
    Code:
    general:
        # Shop tag is what is displayed before most shop output  Default is [Shop].  Improved coloring system coming soon
        shop-tag: '{BKT}[{}Shop{BKT}]{} '
        transactions:
            # Whether or not shop transactions should be logged
            log-transactions: false
            # The file to log transactions in (located in plugins/DynamicMarket)
            log-file: transactions.log
            # If true the file will save after every transaction.  If false the file will save on server shutdown
            log-auto-flush: true
            # Maximum number of items (not bundles) a user is allowed to buy in one transaction
            max-items-buy: 64
            # Maximum number of items (not bundles) a user is allowed to sell in one transaction
            max-items-sell: 64
    database:
        # Database type, either sqlite or mysql
        type: sqlite
        sqlite:
            # The file to store an sqlite database in (lcoated in plugins/DynamicMarket)
            file: shop.db
        mysql:
            # URI for your mysql database
            database: jdbc:mysql://localhost:3306/minecraft
            # MySQL username
            user: root
            # MySQL password
            password: pass
            # MySQL database engine (recommended MyISAM)
            engine: MyISAM
    permissions:
        # If set to true DynamicMarket will ignore the permissions plugin
        # Regular users get 'dynamicmarket.access', 'dynamicmarket.buy', and 'dynamicmarket.sell'
        ignore-permissions: false
        # Whether or not ops should get all permissions
        op-permissions: false


    Changelog (Full Changelog)
    0.6.0
    • Added message.yml file
      • Almost all messages can be configured
      • Colors supported
    • Bug fixes
      • Fixed some settings not being loaded properly
      • No more NullPointerExceptions (hopefully)
    • Improved auto-update script
    0.5.3
    • Converted config file to yml
      • Your DynamicMarket.settings will be converted automatically
    • Fixed inventory space check for items with subtypes
    0.5.2
    • Rewritten API
      • DMWrapper update coming soon
     
    DJ_Idol and Juze like this.
  2. Offline

    STHedgeHog

    Hello. This looks like is could be an excelent plugin, ive got a question and an error message im afraid.
    So the questiong: From what i understand you can use the /shop option anywhere, is there a way to set it to only work in certain places i.e. a shop area?
    And the error: Fresh server 953 with only this and essentials running.
    Code:
    2011-07-04 09:33:29 [INFO] Starting minecraft server version Beta 1.7.2
    2011-07-04 09:33:29 [INFO] Loading properties
    2011-07-04 09:33:29 [INFO] Starting Minecraft server on *:25565
    2011-07-04 09:33:29 [INFO] This server is running Craftbukkit version git-Bukkit-0.0.0-904-g9277096-b953jnks (MC: 1.7.2)
    2011-07-04 09:33:29 [INFO] Preparing level "noisy"
    2011-07-04 09:33:29 [INFO] Preparing start region for level 0 (Seed: -1508825601)
    2011-07-04 09:33:30 [INFO] [DynamicMarket] Initializing Version 0.5.0.
    2011-07-04 09:33:30 [INFO] [DynamicMarket] Permissions plugin not found, defaulting to OP.
    2011-07-04 09:33:30 [SEVERE] [DynamicMarket]: Error executing statement [ALTER TABLE Market RENAME TO Market_backup;CREATE TABLE Market ( id INTEGER PRIMARY KEY AUTOINCREMENT, item INT NOT NULL, subtype INT NOT NULL, name TEXT NOT NULL, count INT NOT NULL, baseprice DECIMAL(64,2) NOT NULL, canbuy INT NOT NULL, cansell INT NOT NULL, stock INT NOT NULL, volatility INT NOT NULL, salestax INT NOT NULL, stockhighest INT NOT NULL, stocklowest INT NOT NULL, stockfloor INT NOT NULL, stockceil INT NOT NULL, pricefloor INT NOT NULL, priceceil INT NOT NULL, jitterperc INT NOT NULL, driftout INT NOT NULL, driftin INT NOT NULL, avgstock INT NOT NULL, class INT NOT NULL, shoplabel TEXT NOT NULL DEFAULT '');CREATE INDEX itemIndex ON Market (item);CREATE INDEX subtypeIndex ON Market (subtype);CREATE INDEX nameIndex ON Market (name);CREATE INDEX shoplabelIndex ON Market (shoplabel);INSERT INTO Market SELECT * FROM Market_backup;DROP TABLE Market_backup;] with sqlite: java.sql.SQLException: there is already another table or index with this name: Market_backup
    2011-07-04 09:33:30 [WARNING] [DynamicMarket] Could not update database!
    2011-07-04 09:33:30 [INFO] [DynamicMarket] Version 0.5.0 (Shaniqua) enabled.
    2011-07-04 09:33:30 [INFO] [DynamicMarket] Linked with Essentials Version 2.2 successfully.
    2011-07-04 09:33:30 [INFO] Loaded Essentials build 2.4.1 by Zenexer, ementalo, Aelux, Brettflan, KimKandor, snowleo, ceulemans and Xeology
    2011-07-04 09:33:30 [INFO] Done (0.117s)! For help, type "help" or "?"
    The database-type is sqlite and there were no extra files in the plugins folder so I dont understand why its throwing the "SQLException: there is already another table or index with this name: Market_backup" error :s
     
  3. Offline

    Luis

    are you using the same formula as haloinverse to calculate the dynamic prices?
     
  4. Offline

    GoalieGuy6

    Yes, the price calculation is still the same. Like I said I've only done some small modifications so far like allowing decimals in prices. As for the error above it shouldn't be attempting to convert the database if you are on a fresh install, I will look into that.

    Also, /shop can be used anywhere. There used to be a wrapper plugin that would allow you to set specific shop areas where it can be used, but I am not sure if that is still being maintained.

    Edit: The download has been updated, delete your DynamicMarket folder in plugins/ and try running the updated jar.
     
  5. Offline

    STHedgeHog

    The new update ifxed my problem, tyvm. Now i can have a play around and see whats what. Ill have a hunt for the wrapper. im sure ive seen somehting like it in another plugin but cant remember where atm :)
     
  6. Oh wow, someone picked this up. Been using this since day one, glad to see it active again on here!

    The wrapper however, never really worked for us, perhaps that feature could just be added to this plugin?
     
  7. Offline

    GoalieGuy6

    I will see if I can find the wrapper and maintain it. I am pretty new to Java though and this is my first real project, so I can't make any promises.

    Version 0.5.2 has been released. This update did not change any functionality, the only change is the rewritten API. You will only need to update to 0.5.2 if you'd like to use the DMWrapper plugin I am working on updating.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 17, 2016
  8. Offline

    Crimsonfox

    Great to see this being updated again. I'm still using that old version that became inactive with the Old DMWrapper. Cheers!
     
  9. Great!

    Can you please make sure the shop location is constrained all all 3 directions. Perhaps ideally make it so you can define a WG region as shop area, that'd be smooth :)
     
  10. Offline

    dumptruckman

    Code:
    2011-07-05 11:48:33 [INFO] [DynamicMarket] Updating database.
    2011-07-05 11:48:33 [SEVERE] [DynamicMarket]: Error executing statement [ALTER TABLE Market ALTER COLUMN baseprice DECIMAL(64,2) NOT NULL] with mysql: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DECIMAL(64,2) NOT NULL' at line 1
    2011-07-05 11:48:33 [SEVERE] [DynamicMarket] Database update failed.
    :( Help

    Edit: Hmm... This seemed to fixed itself after a server restart. A little worrisome, however.
     
  11. Offline

    GoalieGuy6

    I never got a chance to test the database update script for MySQL, thank you for reporting this, I will take a look. When you restarted the server, did it say "Database updated."?

    I will see if WG has an API that I could use for this.
     
  12. Offline

    dumptruckman

    I don't think it did... I looked for something along those lines. It just did it's iConomy hooking messages, I believe. But, it seems to work fine still.
     
  13. Offline

    GoalieGuy6

    I've released an update to DMWrapper here. WorldGuard is optional for defining shop areas, the plugin has it's own selection system if you do not use WorldGuard. I haven't had too much time to test this so there may a couple bugs.

    Also DynamicMarket version 0.5.3 has been released, it changes the plugin's settings file to YAML. Your DynamicMarket.settings should be converted automatically on the first run.
     
  14. Thanks for the update.

    I have a request or bug report. There is an exploit in this when used through command signs. If you build a command sign that sells food, and you activate the shop sell sign, while holding the food, you can sell the food, but the item wont actually be taken.

    I am not sure if this should be fixed in the command signs plugin, but author hasn't responded. Would it be possible to add a config option, that when enabled, only allows shop sell/buy with empty hands? That would be great!

    Well, I am not sure what changed, but our shop is no longer recognizing any item. Also, I see no mention of a mysql database convert in the log. The columns are still type Int in the database.

    Settings look ok?
    Code:
    database:
        type: mysql
        sqlite:
            file: shop.db
        mysql:
            database: jdbc:mysql://localhost:3306/asdasd
            user: asda
            password: asdasd
            engine: InnoDB
    permissions:
        ignore-permissions: false
        op-permissions: false
    
    Not working at all :S

    ===

    Also, I have redownloaded 0.5.3 a few times now, but it keeps saying 0.5.2 on startup, is that just a visual glitch?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 17, 2016
  15. Offline

    GoalieGuy6

    Are you getting any errors in the console? The settings file looks fine and the 0.5.2 is just an error.. I forgot to update the plugin.yml. I am trying to reproduce your problem but everything is running fine as far as I can tell.

    Edit: Sorry I just tried the jar I linked in the main post and see what you mean. I must've gotten the wrong file somewhere, try redownloading it now.
     
  16. No errors, simply every item is suddenly not recognized, and the DB is never updated, so I presume it just can't reach mysql somehow, but without throwing any errors...
     
  17. Offline

    GoalieGuy6

    See the edit in my post above, I made a mistake somewhere and uploaded the wrong jar.
     
  18. Well: 10:20:02 [INFO] [DynamicMarket] Initializing Version 0.5.3.

    So version works, but the DB is not being updated:

    count int(11) No None Browse distinct values Change Drop Primary Unique Index Fulltext
    baseprice int(11) No None
     
  19. Offline

    GoalieGuy6

    I will look into this issue. Sorry for all the MySQL errors, I have not worked with it too much. If you'd like to update the database manually the query to run is below, I'll work in making sure it is fixed in the plugin too.
    Code:
    ALTER TABLE `Market` CHANGE `baseprice` `baseprice` DECIMAL(64,2) NOT NULL
     
  20. This fixed the issues!

    Now back to testing the DMWrapper, as I was having an issue with that I think, but will post in that thread ;)

    Random error trace you may want to catch: http://pastie.org/2171901

    ===

    Regarding above error, something very weird is happening.

    With empty inventory, do:
    /shop buy stone - Buys 1 stack of stone
    /shop buy stone - Error
    Clear inventoy, can buy stone againwithout error Oo

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 17, 2016
  21. Offline

    GoalieGuy6

    Ah that was a glitch with the inventory space check when purchasing an item. Fixed in the 0.6.0 release.
     
  22. Offline

    fatmarley

    There is no physical shop? It is a use anywhere kind?
     
  23. Offline

    GoalieGuy6

    Yes, the shop can be used anywhere. However there is a wrapper plugin that can be used to restrict the /shop command to specific regions.
     
  24. Offline

    fatmarley

    A dynamic market shop is a FANTASTIC idea.

    But honestly I would prefer a physical inventory giving the option for players to run shops.
     
  25. Offline

    GoalieGuy6

    This plugin is meant to provide a global server shop. You do have the option to limit the shop's stock so that if it is out of stock players cannot buy an item until some of that item is sold to the shop, however I am not planning on implementing player-run shops. If you are looking for a good plugin to let your players run their own shops with a physical inventory, I personally recommend iConomyChestShop.
     
  26. Offline

    fatmarley

    But with signs, you dont have a real market economy.

    Thanks all the same.
     
  27. You misunderstand the purpose of this plugin, not to mention there are a gazillion, usually buggy, physical trading shops, this plugin is unique and actually can carry a server-wide economy.
     
  28. Offline

    Bobsajit

    Is there anyway you could add more than one market/shop. The new RP world I am setting up for my server is going to have three major kingdoms, I would like each to have their own dynamic economies. So trading in-between kingdoms, or merchanting would work. Nice work on the plugin by the way, it's such an amazing idea.
     
  29. Offline

    fatmarley

    @Joy I would love to be enlightened

    The only purpose i can see for MY case is to setup infinite shops that a few shop owners can access to stock their physical and usually buggy shops.
     
  30. Offline

    GoalieGuy6

    Credit for the idea goes to @HaloInverse, I just picked up the plugin after it went inactive. Multiple shops are not possible right now, but since it seems to be a fairly commonly requested feature I will see if I can get them added to the todo list.

    With DynamicMarket you are able to setup items that do not have an unlimited stock, so the stock falls when a user buys items and rises when someone sells it. The stock can be limited in both directions such that you can't buy an item if the stock hits its bottom point and you can't sell an item if the stock hits its highest point.
     

Share This Page