diff --git a/.github/GDPDisplay.gif b/.github/GDPDisplay.gif deleted file mode 100644 index 7df77f0..0000000 Binary files a/.github/GDPDisplay.gif and /dev/null differ diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 6bdda54..cf6eb65 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -3,34 +3,24 @@ name: Bug report about: Create a report to help us improve title: "[BUG]" labels: bug -assignees: '' +assignees: 'Unprotesting' --- **Describe the bug** A clear and concise description of what the bug is. -**To Reproduce** +**Steps To Reproduce** Steps to reproduce the behavior: -1. Go to '....' -2. Click on '....' -3. Scroll down to '....' -4. See error **Expected behavior** A clear and concise description of what you expected to happen. -**Screenshots** -If applicable, add screenshots to help explain your problem. - **Minecraft Server Version** -1.18 etc. +1.19 etc. **Auto-Tune-Version** 0.13.0 etc. -**Plugin List** -Essentials, Vault etc. - **Additional context** -Add any other context about the problem here. +Add any other context about the problem here (logs, plugins, etc.) diff --git a/.github/OnlineGraphDisplay.gif b/.github/OnlineGraphDisplay.gif deleted file mode 100644 index c8a512d..0000000 Binary files a/.github/OnlineGraphDisplay.gif and /dev/null differ diff --git a/.github/SellDisplay.gif b/.github/SellDisplay.gif deleted file mode 100644 index a62119f..0000000 Binary files a/.github/SellDisplay.gif and /dev/null differ diff --git a/.github/ShopDisplay.gif b/.github/ShopDisplay.gif deleted file mode 100644 index c476df9..0000000 Binary files a/.github/ShopDisplay.gif and /dev/null differ diff --git a/.github/graph.png b/.github/graph.png deleted file mode 100644 index 15b9c2a..0000000 Binary files a/.github/graph.png and /dev/null differ diff --git a/.github/shop.png b/.github/shop.png deleted file mode 100644 index 5f7c8a1..0000000 Binary files a/.github/shop.png and /dev/null differ diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 8f7c339..f586551 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -1,6 +1,3 @@ -# This workflow will build a Java project with Gradle -# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle - name: Java CI with Gradle on: @@ -11,9 +8,7 @@ on: jobs: build: - runs-on: ubuntu-latest - steps: - uses: actions/checkout@v3 - name: Set up JDK 17 @@ -28,7 +23,7 @@ jobs: - name: Gradle Build Action uses: gradle/gradle-build-action@v2.2.0 with: - arguments: build test + arguments: test build gradle-version: '7.4' - uses: actions/upload-artifact@v2 with: diff --git a/.gitignore b/.gitignore index af51f4b..22d464c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,10 +21,12 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* +# VSCode .settings .vscode + +# Gradle +gradle .gradle -bin build -gradle -tests \ No newline at end of file +bin \ No newline at end of file diff --git a/.project b/.project deleted file mode 100644 index 5f13a88..0000000 --- a/.project +++ /dev/null @@ -1,34 +0,0 @@ - - - Auto-Tune - Project Auto-Tune-1.16.4 created by Buildship. - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.buildship.core.gradleprojectbuilder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.buildship.core.gradleprojectnature - - - - 0 - - 30 - - org.eclipse.core.resources.regexFilterMatcher - node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ - - - - diff --git a/README.md b/README.md index 1fc5503..b2501b2 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +# Auto-Tune + ![GitHub Workflow Status](https://img.shields.io/github/workflow/status/Unprotesting/Auto-Tune/Java%20CI%20with%20Maven) ![GitHub issues](https://img.shields.io/github/issues/Unprotesting/Auto-Tune) ![GitHub pull requests](https://img.shields.io/github/issues-pr/Unprotesting/Auto-Tune) @@ -5,901 +7,66 @@ [![Codacy Badge](https://api.codacy.com/project/badge/Grade/2f6d82bd12af4ce490959be74d1b6149)](https://app.codacy.com/gh/Unprotesting/Auto-Tune?utm_source=github.com&utm_medium=referral&utm_content=Unprotesting/Auto-Tune&utm_campaign=Badge_Grade_Settings) [![Discord](https://img.shields.io/discord/748222485975269508.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/bNVVPe5) -# Auto-Tune - - ### A Powerful Minecraft Automatic-Economy Plugin for ```1.13-1.18``` with many features! - - - - -## Features - - #### What is Auto-Tune? - -Auto-Tune is a Minecraft plugin for server that aims at transforming a part of Minecraft servers often ignored and that remains undeveloped. That is the economy of Minecraft servers. - -There are currently two forms of Minecraft economies that exists on modern servers. The first is vanilla which does not use plugins to assist in functionality within the economy. The second is a server-shop, vanilla blend, this method uses player-to-player trades and a server-wide shop that includes set prices for items to be bought and sold. The second method is often preferred on SMP/vanilla as it provides higher liquidity and engagement in the market than vanilla. However, on anarchy/semi-anarchy servers the vanilla-economy is provided as vanilla mechanics are often preferred. - -Both methods have significant issues. Vanilla being the most obvious with incredibly low engagement in the market as trades are strictly player-to-player bartering. To fix this issue servers and plugin-makers have developed a server-economy. Plugins such as essentials and Vault’s API allows for a medium of exchange within Minecraft. This has drastically fixed a lot of issues with the bartering system within Minecraft. However, the issue of low market engagement persisted. This has had attempts to be “fixed” however, by introducing server-wide shop plugins, often in the form of shop GUI’s or sign-shops. This is the current “preferred” method of economies in Minecraft servers. - -Auto-Tune aims to fix the still present problems in both methods of economies by introducing automatic dynamic pricing powered by Auto-Tune API, an API we have developed that contains various algorithms for calculating prices. Auto-Tune is a powerful, highly customizable plugin that creates a GUI-shop with server-set items that hooks into the Auto-Tune API and updates prices for items based on aggregate supply and demand. Different levels of Auto-Tune unlock access to various pricing models. However the Auto-Tune plugin contains many advanced features standalone; an integrated web-server that creates a website which displays graphs of items on the select server, automatic selling, volatility settings, sell price difference variation, and more. Our team at Auto-Tune is optimistic and passionate about Minecraft, plugin development and improving the community as a whole and are working hard at improving the plugin which is still deep in development. - -An example of a graph for an item created by the algorithm displayed online: - - - -An example of a shop setup using Auto-Tune: - - - - #### Feature List - - - ```Advanced pricing model.``` - - ```Contains 7 pricing model options. [Volatility Options and algorithm, data-selection-algorithm, and more].``` - - ```2 integrated web-servers to display prices online in graphs [Server port settings and more].``` - - ```Configurable GUI with sizing, positioning and naming options.``` - - ```Configurable shops with options to lock price and sell-price-differences [For more look at shops.yml configuration below].``` - - ```Configurable sell-price-difference.``` - - ```Stored detailed history of transactions.``` - - ```Sell price-difference-variation algorithm options [Update period, total time, starting-difference, ending difference].``` - - ```Player loaning including an easy loaning GUI.``` - - ```Configurable interest rates [Update period, amount and more].``` - - ```Debt settings.``` - - ```Exploit protection.``` - - ```GDP and GDP per capita calculation [factors in buying/selling, debt, and loaning, using /gdp].``` - - ```Much more economy info such as server-balance debt, loss, and inflation.``` - - ```Incredibly fast data-collection and creation.``` - - ```Data corruption protection.``` - - ```Configurable messages.``` - - ```Fully configurable tutorial.``` - - ```Configurable automatic selling command for players.``` - - ```Data export and import.``` - - ```And more!``` - - ```Many more features coming soon.``` - -## Usage - - #### To use Auto-Tune - - - Note: Make sure you have a valid API key. - - Download the latest version of Auto-Tune from the resources tab for your Minecraft server's Minecraft version - Make sure the dependencies are also installed ([Vault](https://www.spigotmc.org/resources/vault.34315/) and any economy plugin such as [Essentials](https://essentialsx.net)). An optional dependency is [PlaceholderAPI](https://www.spigotmc.org/resources/placeholderapi.6245/). - - Put the .jar file in your Minecraft ```/plugins``` folder. - - Restart your server. - - Edit the ```config.yml``` file inside ```/plugins/Auto-Tune/```, and enter your API key and email (check Auto-Tune API for more). - - Edit any other settings you want, in the ```config.yml``` file. - - Edit the ```shops.yml``` file to include items you wish to have in your shop. - - Restart your server, again. - - Auto-Tune will be running on your server, do ```/shop``` to view the items you set in the ```shops.yml``` file. - - For more information view our [Wiki](https://github.com/Unprotesting/Auto-Tune/wiki). - - #### To build the project yourself - - - Clone the project to a local directory using ```git clone https://github.com/Unprotesting/Auto-Tune.git ```. - - Run ```cd Auto-Tune``` to enter the Auto-Tune folder. - - Run ```./gradlew build```. - - Navigate to the ```/builds/libs/``` directory and Auto-Tune-0.x.x will be there if successful. - - In addition all the latest builds are available under the [Actions](https://github.com/Unprotesting/Auto-Tune/actions) section of the github. - Simply go the latest action and download the 'artifact' file, then unzip it, and the .jar will be inside. - - #### Configuring config.yml -
- Config.yml - - Auto-Tune's Config.yml file: - -``` - -# ░█████╗░██╗░░░██╗████████╗░█████╗░░░░░░░████████╗██╗░░░██╗███╗░░██╗███████╗ -# ██╔══██╗██║░░░██║╚══██╔══╝██╔══██╗░░░░░░╚══██╔══╝██║░░░██║████╗░██║██╔════╝ -# ███████║██║░░░██║░░░██║░░░██║░░██║█████╗░░░██║░░░██║░░░██║██╔██╗██║█████╗░░ -# ██╔══██║██║░░░██║░░░██║░░░██║░░██║╚════╝░░░██║░░░██║░░░██║██║╚████║██╔══╝░░ -# ██║░░██║╚██████╔╝░░░██║░░░╚█████╔╝░░░░░░░░░██║░░░╚██████╔╝██║░╚███║███████╗ -# ╚═╝░░╚═╝░╚═════╝░░░░╚═╝░░░░╚════╝░░░░░░░░░░╚═╝░░░░╚═════╝░╚═╝░░╚══╝╚══════╝ - -## -- Auto-Tune Config File -- ## - -## See the wiki for info on each setting: https://github.com/Unprotesting/Auto-Tune/wiki - -## -- General Settings -- ## - -## API key given on sign-up -api-key: 'xyz' - -## Email used on sign-up -email: 'xyz@gmail.com' - -## Enable/Disable integrated Web Server. -## Info: Use /trade to view the web-server -web-server-enabled: true - -## Port for integrated Web Server (If enabled) -## Make sure to port-forward and disable firewalls for this port. -port: 8123 - -## The maximum length in data points that the trade-short.html will show (this doesn't affect data) -## Info: When the time-period is set to 30, a maximum-short-trade-length of 48 is one day. -maximum-short-trade-length: 50 - -## Time Period in minutes -## Info: When decreasing or increasing this adjust your volatility settings accordingly -time-period: 30 - -## GUI Shop Menu title -menu-title: 'Shop' - -## GUI Shop Menu background -## Info: Use 'NONE' for no background -background: 'BLACK_STAINED_GLASS_PANE' - -## How often auto-sell updates in ticks -## Info: Set this higher if few players use autosell -## Info: Set it lower if many players use autosell -auto-sell-update-period: 10 - -## How often players are shown their auto-sell profits in ticks -auto-sell-profit-update-period: 600 - -## Global number format -number-format: '###,###,###,###,##0.00' - -## Enable Enchantments -enable-enchantments: true - -## -- Pricing Model Settings -- ## - -## Percentage difference in sell price to buy price -sell-price-difference: 10.0 - -## Maximum Volatility per Time Period for the Variable Volatility price calculation algorithm as a percentage of total price -max-volatility: 0.5 - -## Minimum Volatility per Time Period for the Fixed Volatility price calculation algorithm in economy units -min-volatility: 0.05 - -## -- Data Selection Settings -- ## - -## Info: When setting your data selection algorithm use a site such as https://www.desmos.com/calculator -## Info: Data selection uses the equation y=m(x^z)+c, for example the default is y=0.075(x^(1.6))+0.55 - -## 'm' in equation: y=m(x^z)+c -data-selection-m: 0.05 - -## 'z' in equation: y=m(x^z)+c -data-selection-z: 1.75 - -## 'c' in equation: y=m(x^z)+c -data-selection-c: 0.55 - -## -- Other Economy Settings -- - -## Minimum players needed, to be online, for prices to update -## Info: It is recommended to keep this above 0 -update-prices-threshold: 1 - -## The symbol that appears before all currency -currency-symbol: '$' - -## Enable sell price difference variation to ease out sell price variation -sell-price-difference-variation-enabled: true - -## Starting percentage sell price difference for sell price variation -sell-price-difference-variation-start: 30.0 - -## Time in minutes until sell price reaches sell-price-difference set in pricing model settings (default 4 weeks) -sell-price-variation-time-period: 43200 - -## Time in minutes that the sell-price-difference updates -sell-price-variation-update-period: 30 - -## Interest rate per interest-rate-update-period -## Info: This is the increase in the current debt payment per-time period -interest-rate: 0.025 - -## Time period in ticks between updates of the interest rate for users loans -interest-rate-update-period: 1200 - -## Disable the max-buy/max-sells for items -## Info: Don't do this unless you know what your doing. -## Info: If this is enabled, it is likely to lead to exploitation on servers with under 10 concurrent players -disable-max-buys-sells: false - -## The lowest value in $ a player can go into debt -## For example if a player has $3,000 and this is set to 1000 a player can take out a loan up to $2,000 -max-debt-value: 1000.0 - -## The percentage value to decrease items sold with enchantments -## Info: Stacked enchantments etc. can become very expensive so a number between 30% - 60% is usually fine -## Info: This doesn't affect buys -enchantment-limiter: 50.0 - -## The percentage value to decrease items sold with a loss in durability -## Info: This is applied ON TOP of the durability algorithm to limit the exploit-ability of selling tools -durability-limiter: 10.0 - -## -- Other Settings -- - -## Enable debug mode for more info on price calculations -debug-enabled: false - -## Ignore AFK players in price calculations/online checks -## Info: Turning this on will mean the price will only update when there's a player that is not AFK -## Info: This only applies to essentials AFK and you must have essentials installed for this to work -ignore-afk: true - -## Enable ChecksumHeaderBypass if you have issues with data retrieval or corruption -## Info: This is a very rare occurrence and should only be used if you have issues with data retrieval or corruption -checksum-header-bypass: true - -## Enable the Auto-Tune tutorial for players (the messages that are displayed to players periodically) -## Keep this on to encourage purchasing turn it off if it is distracting -tutorial: true - -## Time in seconds between messages -tutorial-message-period: 325 - -## Data storage location -data-location: 'plugins/Auto-Tune/' - -## Enable transactions -## Info: This will result in much larger file sizes and additional transaction files but more stability and improved data-protection -## Info: This is off by default as the default data protection will be fine for most servers -data-transactions: false - -## Read initial price data and buys/sells from trade.csv -## Stop server, set this to true, delete data.db, import your trade.csv, start the server, set this to false, restart server -read-from-csv: false +>A Powerful Minecraft Automatic-Economy Plugin for ```1.13-1.19``` with many features! + -``` -
+## :star: Overview - #### Configuring shops.yml - -
- Shops.yml - - Auto-Tune's Shops.yml file: +*Auto-Tune is a Minecraft plugin that allows you to create an automated economy for your server. Prices of items will be automatically adjusted based on supply and demand. When an item is purchased by many players but sold by few, Auto-Tune will raise the price to lower demand/increase supply and vice versa. Auto-Tune fixes a critical problem in Minecraft server economies and provides a better experience for players and servers. You can check out our feature set below.* -``` +## :heavy_check_mark: Features -# ░█████╗░██╗░░░██╗████████╗░█████╗░░░░░░░████████╗██╗░░░██╗███╗░░██╗███████╗   -# ██╔══██╗██║░░░██║╚══██╔══╝██╔══██╗░░░░░░╚══██╔══╝██║░░░██║████╗░██║██╔════╝   -# ███████║██║░░░██║░░░██║░░░██║░░██║█████╗░░░██║░░░██║░░░██║██╔██╗██║█████╗░░   -# ██╔══██║██║░░░██║░░░██║░░░██║░░██║╚════╝░░░██║░░░██║░░░██║██║╚████║██╔══╝░░   -# ██║░░██║╚██████╔╝░░░██║░░░╚█████╔╝░░░░░░░░░██║░░░╚██████╔╝██║░╚███║███████╗   -# ╚═╝░░╚═╝░╚═════╝░░░░╚═╝░░░░╚════╝░░░░░░░░░░╚═╝░░░░╚═════╝░╚═╝░░╚══╝╚══════╝   +- :ballot_box_with_check: ```Advanced automatic pricing model based on supply and demand``` +- :ballot_box_with_check: ```Configurable GUI shop, with positioning and naming options``` +- :ballot_box_with_check: ```Easy selling panel to sell items quickly``` +- :ballot_box_with_check: ```Automatic selling, configurable player side``` +- :ballot_box_with_check: ```Fully supports all enchantments and items``` +- :ballot_box_with_check: ```Stored detailed history of transactions``` +- :ballot_box_with_check: ```Exploit protection with max-buys/sells, volatility settings, and more``` +- :ballot_box_with_check: ```Limit player's to only be able to purchase items they have collected before``` +- :ballot_box_with_check: ```Advanced loaning with interest settings``` +- :ballot_box_with_check: ```Integrated web-server for viewing price information``` +- :ballot_box_with_check: ```Calculates GDP, debt, inflation and more``` +- :ballot_box_with_check: ```Incredibly fast data collection and creation with corruption protection``` +- :ballot_box_with_check: ```All messages are configurable``` +- :ballot_box_with_check: ```Tutorial to help new players``` +- :ballot_box_with_check: ```And much, much more...``` -## -- Auto-Tune Shops File -- ## +## :question: Why use Auto-Tune -## See the wiki for info on each setting: https://github.com/Unprotesting/Auto-Tune/wiki +Auto-Tune identifies and fixes a significant problem in Minecraft servers that has remained underdeveloped and ignored for too long. This issue is the poor implementation of an economy and markets into Minecraft. -## Shop sections configuration -sections: - 'Natural Resources': - ## Block that the section image is displayed as - block: 'IRON_ORE' - ## Background for sub-menu - ## Use 'NONE' for no background - background: 'GRAY_STAINED_GLASS_PANE' - ## Position in Main Menu GUI - position: 10 - ## Optional - set to disabled to disable the back button when running "/shop ". - ## This wont disable the back button when running just "/shop" - back-menu-button-enabled: true - ## Set the display name for the section - display-name: '&6Natural Resources' - 'Blocks': - block: 'STONE' - position: 12 - background: 'GRAY_STAINED_GLASS_PANE' - back-menu-button-enabled: true - display-name: '&6Blocks' - 'Food': - block: 'COOKED_BEEF' - position: 14 - background: 'GRAY_STAINED_GLASS_PANE' - back-menu-button-enabled: true - display-name: '&6Food' - 'Farming': - block: 'OAK_SAPLING' - position: 16 - background: 'GRAY_STAINED_GLASS_PANE' - back-menu-button-enabled: true - display-name: '&6Farming' - 'Tools': - block: 'DIAMOND_PICKAXE' - position: 20 - background: 'GRAY_STAINED_GLASS_PANE' - back-menu-button-enabled: true - display-name: '&6Tools' - 'Other': - block: 'STICK' - position: 24 - background: 'GRAY_STAINED_GLASS_PANE' - back-menu-button-enabled: true - display-name: '&6Other' +Previous solutions that allow for trading between players have lacked flexibility, player engagement, and realism. These issues are due to server economy plugins that cannot adapt to the speed at which the economy in Minecraft changes. We designed Auto-Tune with this in mind. By automating the price-setting process, server admins can sit back and watch the prices fluctuate as the supply and demand of items bounce back and forth. -## Set the default / starting prices for the items you want available in the shop. -## IMPORTANT: Thee prices of these items can't be changed once the database has been created. -## IMPORTANT: To change the price of items use /at price or reset the data.db file. -## Info: Material names are available here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html. -## IMPORTANT: Material names are case sensitive! (All caps and underscores) -## Options: 'price: ' set the default starting price of the item. -## Options: 'section: ' set the section of this item. -## Options: 'locked: ' set the price to be locked or variable (variable by default). -## Options: 'sell-difference: ' set a custom sell-price-difference (default set in config). -## Options: 'max-buy': set a maximum quantity that can be purchased in a time-period. -## Options: 'max-sell': set a maximum quantity that can be sold in a time-period. -## Options: 'max-volatility: ' set the maximum volatility per time-period for this individual item. -## Options: 'min-volatility: ' set the minimum volatility per time-period for this individual item. -## Options: 'display-name': ' set the display name of the item. -## Options: 'collect-first-setting': ' ('NONE'|'SERVER_WIDE'|'EACH_PLAYER') whether the item needs to be collected before it can be purchased. +Not only does this assist administrators in managing a server's economy, but it also allows the server players to engage with the economy more rigorously. We have strenuously tested Auto-Tune to be fit for any environment and created systems designed to assist server admins in building the best economy possible for the specific needs of their server. Auto-Tune is a powerful and highly customizable plugin that has a feature set rich enough to satisfy any server. We at Auto-Tune are passionate and optimistic about Minecraft plugin development and building a community that loves Minecraft and economics! +## :computer: Usage - ## Example: - ## GRASS_BLOCK: - ## price: 50.00 - ## section: 'Blocks' This item will exist within the 'Blocks' shop-section - ## locked: true <- Example of a locked item - ## sell-difference: 0.0 <- Example of a set sell-difference item - ## max-buy: 10 <- Only 10 items can be bought each time-period - you can increase this on large servers - ## max-sell: 12 <- Only 12 items can be sold each time-period - you can increase this on large servers - ## max-volatility: 0.25 <- Example of an item with a lower max-volatility - ## min-volatility: 0.05 <- Example of an item with a higher min-volatility - ## display-name: '&aGrass' <- Example of a custom display name (with a green color code) - ## collect-first-setting: 'EACH_PLAYER' <- Example of a custom collect-first-setting +### :clipboard: Server setup -shops: - COAL: - price: 15.00 - max-buy: 80 - max-sell: 115 - section: 'Natural Resources' - IRON_INGOT: - price: 17.00 - max-buy: 75 - max-sell: 100 - section: 'Natural Resources' - COPPER_INGOT: - price: 20.00 - max-buy: 64 - max-sell: 80 - section: 'Natural Resources' - GOLD_INGOT: - price: 25.00 - max-buy: 45 - max-sell: 75 - section: 'Natural Resources' - DIAMOND: - price: 325.00 - max-buy: 15 - max-sell: 32 - section: 'Natural Resources' - AMETHYST_SHARD: - price: 22.00 - max-buy: 32 - max-sell: 45 - section: 'Natural Resources' - LAPIS_LAZULI: - price: 12.00 - max-buy: 128 - max-sell: 256 - section: 'Natural Resources' - EMERALD: - price: 145.00 - max-buy: 12 - max-sell: 32 - section: 'Natural Resources' - QUARTZ: - price: 11.00 - max-buy: 40 - max-sell: 125 - section: 'Natural Resources' - REDSTONE: - price: 8.00 - max-buy: 80 - max-sell: 128 - section: 'Natural Resources' - NETHERITE_INGOT: - price: 8500.00 - max-buy: 1 - max-sell: 2 - section: 'Natural Resources' - GLOWSTONE_DUST: - price: 4.00 - max-buy: 128 - max-sell: 256 - section: 'Natural Resources' - DIRT: - price: 0.5 - max-buy: 512 - max-sell: 1024 - section: 'Blocks' - COBBLESTONE: - price: 1.00 - max-buy: 256 - max-sell: 800 - section: 'Blocks' - STONE: - price: 2.00 - max-buy: 128 - max-sell: 256 - section: 'Blocks' - GRAVEL: - price: 3.00 - max-buy: 128 - max-sell: 256 - section: 'Blocks' - SAND: - price: 1.00 - max-buy: 128 - max-sell: 500 - section: 'Blocks' - SANDSTONE: - price: 4.00 - max-buy: 100 - max-sell: 250 - section: 'Blocks' - OBSIDIAN: - price: 15.00 - max-buy: 20 - max-sell: 64 - section: 'Blocks' - END_STONE: - price: 3.50 - max-buy: 80 - max-sell: 200 - section: 'Blocks' - NETHERRACK: - price: 1.00 - max-buy: 256 - max-sell: 1024 - section: 'Blocks' - WHITE_WOOL: - price: 6.50 - max-buy: 64 - max-sell: 80 - section: 'Blocks' - OAK_LOG: - price: 8.00 - max-buy: 90 - max-sell: 256 - section: 'Blocks' - MOSS_BLOCK: - price: 35.00 - max-buy: 15 - max-sell: 32 - section: 'Blocks' - CACTUS: - price: 3.00 - max-buy: 64 - max-sell: 200 - section: 'Farming' - VINE: - price: 2.00 - max-buy: 64 - max-sell: 256 - section: 'Farming' - CARROT: - price: 4.00 - max-buy: 80 - max-sell: 256 - section: 'Food' - MELON_SLICE: - price: 1.75 - max-buy: 85 - max-sell: 175 - section: 'Food' - POTATO: - price: 2.25 - max-buy: 80 - max-sell: 120 - section: 'Food' - APPLE: - price: 4.00 - max-buy: 64 - max-sell: 100 - section: 'Food' - WHEAT: - price: 2.00 - max-buy: 128 - max-sell: 256 - section: 'Farming' - SUGAR_CANE: - price: 1.50 - max-buy: 164 - max-sell: 256 - section: 'Farming' - BEEF: - price: 2.50 - max-buy: 64 - max-sell: 150 - section: 'Food' - PORKCHOP: - price: 2.25 - max-buy: 64 - max-sell: 150 - section: 'Food' - CHICKEN: - price: 1.45 - max-buy: 64 - max-sell: 150 - section: 'Food' - RABBIT: - price: 2.50 - max-buy: 64 - max-sell: 150 - section: 'Food' - MUTTON: - price: 2.00 - max-buy: 64 - max-sell: 150 - section: 'Food' - PUMPKIN: - price: 8.00 - max-buy: 64 - max-sell: 128 - section: 'Farming' - COD: - price: 6.00 - max-buy: 96 - max-sell: 124 - section: 'Food' - WHEAT_SEEDS: - price: 1.25 - max-buy: 80 - max-sell: 200 - section: 'Farming' - NETHER_WART: - price: 4.00 - max-buy: 64 - max-sell: 200 - section: 'Farming' - FLINT: - price: 4.00 - max-buy: 64 - max-sell: 128 - section: 'Other' - GUNPOWDER: - price: 12.50 - max-buy: 64 - max-sell: 128 - section: 'Other' - LEATHER: - price: 20.00 - max-buy: 64 - max-sell: 128 - section: 'Other' - INK_SAC: - price: 2.50 - max-buy: 32 - max-sell: 64 - section: 'Other' - FEATHER: - price: 4.00 - max-buy: 32 - max-sell: 64 - section: 'Other' - BONE: - price: 6.00 - max-buy: 64 - max-sell: 100 - section: 'Other' - STRING: - price: 4.00 - max-buy: 64 - max-sell: 100 - section: 'Other' - ROTTEN_FLESH: - price: 0.50 - max-buy: 64 - max-sell: 128 - section: 'Food' - SPIDER_EYE: - price: 7.00 - max-buy: 64 - max-sell: 128 - section: 'Other' - SLIME_BALL: - price: 25.00 - max-buy: 32 - max-sell: 64 - section: 'Other' - ENDER_PEARL: - price: 45.00 - max-buy: 8 - max-sell: 20 - section: 'Other' - NETHER_STAR: - price: 15000.00 - max-buy: 1 - max-sell: 1 - section: 'Other' - BLAZE_ROD: - price: 85.00 - max-buy: 6 - max-sell: 15 - section: 'Other' - ARROW: - price: 2.00 - max-buy: 64 - max-sell: 128 - section: 'Other' - OAK_PLANKS: - price: 0.5 - max-buy: 128 - max-sell: 256 - section: 'Blocks' - BIRCH_PLANKS: - price: 0.5 - max-buy: 128 - max-sell: 256 - section: 'Blocks' - SPRUCE_PLANKS: - price: 0.5 - max-buy: 128 - max-sell: 256 - section: 'Blocks' - JUNGLE_PLANKS: - price: 0.5 - max-buy: 128 - max-sell: 256 - section: 'Blocks' - DARK_OAK_PLANKS: - price: 0.5 - max-buy: 128 - max-sell: 256 - section: 'Blocks' - ACACIA_PLANKS: - price: 0.5 - max-buy: 128 - max-sell: 256 - section: 'Blocks' - OAK_SAPLING: - price: 2.5 - max-buy: 32 - max-sell: 64 - section: 'Farming' - STICK: - price: 0.2 - max-buy: 64 - max-sell: 128 - section: 'Other' - BOOK: - price: 22.0 - max-buy: 20 - max-sell: 32 - section: 'Other' - WOODEN_PICKAXE: - price: 8.0 - max-buy: 4 - max-sell: 8 - section: 'Tools' - WOODEN_AXE: - price: 7.5 - max-buy: 4 - max-sell: 8 - section: 'Tools' - WOODEN_SWORD: - price: 6.5 - max-buy: 4 - max-sell: 8 - section: 'Tools' - WOODEN_SHOVEL: - price: 3.5 - max-buy: 4 - max-sell: 8 - section: 'Tools' - WOODEN_HOE: - price: 3.5 - max-buy: 4 - max-sell: 8 - section: 'Tools' - STONE_PICKAXE: - price: 11.0 - max-buy: 4 - max-sell: 8 - section: 'Tools' - STONE_AXE: - price: 10.5 - max-buy: 4 - max-sell: 8 - section: 'Tools' - STONE_SWORD: - price: 9.0 - max-buy: 4 - max-sell: 8 - section: 'Tools' - STONE_SHOVEL: - price: 5.0 - max-buy: 4 - max-sell: 8 - section: 'Tools' - STONE_HOE: - price: 5.0 - max-buy: 4 - max-sell: 8 - section: 'Tools' - GOLDEN_PICKAXE: - price: 12.0 - max-buy: 3 - max-sell: 8 - section: 'Tools' - GOLDEN_AXE: - price: 11.5 - max-buy: 3 - max-sell: 8 - section: 'Tools' - GOLDEN_SWORD: - price: 10.0 - max-buy: 3 - max-sell: 8 - section: 'Tools' - GOLDEN_SHOVEL: - price: 6.0 - max-buy: 3 - max-sell: 8 - section: 'Tools' - GOLDEN_HOE: - price: 6.0 - max-buy: 3 - max-sell: 8 - section: 'Tools' - IRON_PICKAXE: - price: 18.0 - max-buy: 3 - max-sell: 6 - section: 'Tools' - IRON_AXE: - price: 17.5 - max-buy: 3 - max-sell: 6 - section: 'Tools' - IRON_SWORD: - price: 13.0 - max-buy: 3 - max-sell: 6 - section: 'Tools' - IRON_SHOVEL: - price: 7.0 - max-buy: 3 - max-sell: 6 - section: 'Tools' - IRON_HOE: - price: 7.0 - max-buy: 3 - max-sell: 6 - section: 'Tools' - DIAMOND_PICKAXE: - price: 260.0 - max-buy: 2 - max-sell: 3 - section: 'Tools' - DIAMOND_AXE: - price: 250.0 - max-buy: 2 - max-sell: 3 - section: 'Tools' - DIAMOND_SWORD: - price: 180.0 - max-buy: 2 - max-sell: 3 - section: 'Tools' - DIAMOND_SHOVEL: - price: 110.0 - max-buy: 2 - max-sell: 3 - section: 'Tools' - DIAMOND_HOE: - price: 110.0 - max-buy: 2 - max-sell: 3 - section: 'Tools' - LEATHER_HELMET: - price: 22.50 - max-buy: 2 - max-sell: 4 - section: 'Tools' - LEATHER_CHESTPLATE: - price: 46.00 - max-buy: 2 - max-sell: 3 - section: 'Tools' - LEATHER_LEGGINGS: - price: 25.50 - max-buy: 2 - max-sell: 3 - section: 'Tools' - LEATHER_BOOTS: - price: 20.00 - max-buy: 2 - max-sell: 4 - section: 'Tools' - IRON_HELMET: - price: 45.50 - max-buy: 2 - max-sell: 4 - section: 'Tools' - IRON_CHESTPLATE: - price: 86.00 - max-buy: 2 - max-sell: 3 - section: 'Tools' - IRON_LEGGINGS: - price: 65.50 - max-buy: 2 - max-sell: 3 - section: 'Tools' - IRON_BOOTS: - price: 38.00 - max-buy: 2 - max-sell: 4 - section: 'Tools' - GOLDEN_HELMET: - price: 40.50 - max-buy: 2 - max-sell: 4 - section: 'Tools' - GOLDEN_CHESTPLATE: - price: 80.00 - max-buy: 2 - max-sell: 3 - section: 'Tools' - GOLDEN_LEGGINGS: - price: 60.50 - max-buy: 2 - max-sell: 3 - section: 'Tools' - GOLDEN_BOOTS: - price: 30.00 - max-buy: 2 - max-sell: 4 - section: 'Tools' - DIAMOND_HELMET: - price: 425.50 - max-buy: 2 - max-sell: 4 - section: 'Tools' - DIAMOND_CHESTPLATE: - price: 900.00 - max-buy: 2 - max-sell: 3 - section: 'Tools' - DIAMOND_LEGGINGS: - price: 620.50 - max-buy: 2 - max-sell: 3 - section: 'Tools' - DIAMOND_BOOTS: - price: 350.00 - max-buy: 2 - max-sell: 4 - section: 'Tools' - FISHING_ROD: - price: 25.00 - max-buy: 3 - max-sell: 4 - section: 'Tools' - BOW: - price: 28.00 - max-buy: 3 - max-sell: 4 - section: 'Tools' +1. Download the latest version of Auto-Tune from the [releases](https://github.com/Unprotesting/Auto-Tune/releases) tab on Github. +2. Please use [Paper](https://papermc.io/) or a fork of Paper as your server software. +3. Make sure the required dependencies are installed ([Vault](https://www.spigotmc.org/resources/vault.34315/) and an economy plugin such as [Essentials](https://essentialsx.net)) +4. Put the ```.jar``` files in the ```/plugins``` folder of your server. +5. Start/restart the server. +6. Edit your configuration settings in ```config.yml```, ```shops.yml``` and ```messages.yml```. +7. Restart the server again and Auto-Tune will be running with all your settings configured. -``` -
+### :hammer: Building from source -## Auto-Tune-API +1. Clone the project to a local directory using ```git clone https://github.com/Unprotesting/Auto-Tune.git```. +2. Run ```cd Auto-Tune``` to enter the Auto-Tune folder. +3. Run ```./gradlew build``` to build the project using Gradle. +4. Navigate to the ```/builds/libs/``` directory and ```Auto-Tune-0.x.x``` will be there if the build was successful. - #### What is Auto-Tune API +### :sparkles: Contributing to the project -Auto-Tune API is the API Auto-Tune connects to in order to start the server. The pricing mechanism is now local. -It will be used in the future to perform many tasks. -You still need an API key, for every version of Auto-Tune. - - #### How to get an Auto-Tune API key +Feel free to create a fork of the repository and open a pull request to contribute. If you have any serious issues please report them on the issues tab. For other problems please use the discord below. Please respect the license. -Auto-Tune API key's are free. -To get an Auto-Tune API key please open a ticket on our discord: +## :bell: Join the community -[![Discord](https://img.shields.io/discord/748222485975269508.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/bNVVPe5). \ No newline at end of file +> [![Discord](https://img.shields.io/discord/748222485975269508.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/bNVVPe5) +> +> :email: *unprotesting.email@gmail.com* +> +> :calling: **Unprotesting#3616** diff --git a/build.gradle b/build.gradle index bf4f73a..9a28e16 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { } group 'unprotesting.com.github' -version '0.13.1' +version '0.14.0-pre-release' java { @@ -35,9 +35,9 @@ dependencies { compileOnly('com.github.milkbowl:VaultAPI:1.7.1') { exclude group: "org.bukkit", module: "bukkit" } - - implementation 'org.mapdb:mapdb:3.0.8' + implementation 'org.bstats:bstats-bukkit:2.2.1' + implementation 'org.mapdb:mapdb:3.0.8' implementation 'com.github.stefvanschie.inventoryframework:IF:0.10.6' compileOnly 'io.papermc.paper:paper-api:1.19-R0.1-SNAPSHOT' @@ -56,10 +56,30 @@ dependencies { shadowJar { - archiveName("Auto-Tune-${project.version}.jar") + dependencies { + exclude(dependency('org.eclipse.collections:eclipse-collections-api')) + exclude(dependency('org.eclipse.collections:eclipse-collections')) + exclude(dependency('org.eclipse.collections:eclipse-collections-forkjoin')) + exclude(dependency('com.google.guava:guava')) + exclude(dependency('net.jpountz.lz4:lz4')) + exclude(dependency('org.jetbrains.kotlin:kotlin-stdlib')) + exclude(dependency('com.google.code.findbugs:jsr305')) + exclude(dependency('com.google.errorprone:error_prone_annotations')) + exclude(dependency('com.google.guava:failureaccess')) + exclude(dependency('com.google.guava:listenablefuture')) + exclude(dependency('com.google.j2objc:j2objc-annotations')) + exclude(dependency('org.checkerframework:checker-qual')) + exclude(dependency('org.jetbrains:annotations')) + exclude(dependency('org.jetbrains.kotlin:kotlin-stdlib-common')) + } + + relocate "org.bstats", "unprotesting.com.github.bstats" + relocate "org.mapdb", "unprotesting.com.github.mapdb" + relocate "com.github.stefvanschie.inventoryframework", "unprotesting.com.github.inventoryframework" - relocate 'org.bstats', 'unprotesting.com.github.bstats' - relocate 'com.github.stefvanschie.inventoryframework', 'unprotesting.com.github.inventoryframework' + minimize() + + archiveName("Auto-Tune-${project.version}.jar") } diff --git a/src/main/java/unprotesting/com/github/AutoTune.java b/src/main/java/unprotesting/com/github/AutoTune.java new file mode 100644 index 0000000..a365a58 --- /dev/null +++ b/src/main/java/unprotesting/com/github/AutoTune.java @@ -0,0 +1,86 @@ +package unprotesting.com.github; + +import lombok.Getter; + +import org.bstats.bukkit.Metrics; +import org.bukkit.Bukkit; +import org.bukkit.plugin.java.JavaPlugin; + +import unprotesting.com.github.commands.AutosellCommand; +import unprotesting.com.github.commands.LoanCommand; +import unprotesting.com.github.commands.SellCommand; +import unprotesting.com.github.commands.ShopCommand; +import unprotesting.com.github.config.Config; +import unprotesting.com.github.data.Database; +import unprotesting.com.github.events.AutoTuneInventoryCheckEvent; +import unprotesting.com.github.events.AutosellProfitEvent; +import unprotesting.com.github.events.IpCheckEvent; +import unprotesting.com.github.events.LoanInterestEvent; +import unprotesting.com.github.events.TimePeriodEvent; +import unprotesting.com.github.events.TutorialEvent; +import unprotesting.com.github.util.EconomyUtil; + +@Getter +public class AutoTune extends JavaPlugin { + + @Getter + // The static instance of the plugin. + private static AutoTune instance; + + @Override + public void onEnable() { + instance = this; + EconomyUtil.setupLocalEconomy(Bukkit.getServer()); + Config.init(); + new Database(); + setupEvents(); + setupCommands(); + new Metrics(this, 9687); + getLogger().info("Auto-Tune is now enabled!"); + } + + @Override + public void onDisable() { + Database.get().close(); + getLogger().info("Auto-Tune is now disabled!"); + } + + private void setupCommands() { + getCommand("shop").setExecutor(new ShopCommand()); + getCommand("sell").setExecutor(new SellCommand()); + getCommand("autosell").setExecutor(new AutosellCommand()); + getCommand("loan").setExecutor(new LoanCommand()); + } + + private void setupEvents() { + + Bukkit.getScheduler().runTaskAsynchronously(this, () -> + Bukkit.getPluginManager().callEvent(new IpCheckEvent(true))); + + Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> + Bukkit.getPluginManager().callEvent(new AutosellProfitEvent(true)), + 1200L, 1200L); + + Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> + Bukkit.getPluginManager().callEvent(new LoanInterestEvent(true)), + 1200L, 1200L); + + Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> + Bukkit.getPluginManager().callEvent(new TimePeriodEvent(true)), + (long) (Config.get().getTimePeriod() * 1200L), + (long) (Config.get().getTimePeriod() * 1200L)); + + Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> + Bukkit.getPluginManager().callEvent(new TutorialEvent(true)), + (long) (Config.get().getTutorialUpdate() * 20), + (long) (Config.get().getTutorialUpdate() * 20)); + + Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> + Bukkit.getPluginManager().callEvent(new AutoTuneInventoryCheckEvent(true)), + 200L, 4L); + + } + + + +} diff --git a/src/main/java/unprotesting/com/github/Main.java b/src/main/java/unprotesting/com/github/Main.java deleted file mode 100644 index 6de281d..0000000 --- a/src/main/java/unprotesting/com/github/Main.java +++ /dev/null @@ -1,243 +0,0 @@ -package unprotesting.com.github; - -import java.text.DecimalFormat; -import java.util.logging.Level; - -import lombok.Getter; -import lombok.Setter; - -import net.ess3.api.IEssentials; -import net.kyori.adventure.text.minimessage.MiniMessage; - -import org.bstats.bukkit.Metrics; -import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.java.JavaPlugin; - -import unprotesting.com.github.commands.AutoTuneCommand; -import unprotesting.com.github.commands.AutosellCommand; -import unprotesting.com.github.commands.GdpCommand; -import unprotesting.com.github.commands.LoanCommand; -import unprotesting.com.github.commands.SellCommand; -import unprotesting.com.github.commands.ShopCommand; -import unprotesting.com.github.commands.TradeCommand; -import unprotesting.com.github.commands.TransactionsCommand; -import unprotesting.com.github.config.Config; -import unprotesting.com.github.config.DataFiles; -import unprotesting.com.github.config.Messages; -import unprotesting.com.github.data.csv.CsvHandler; -import unprotesting.com.github.data.ephemeral.LocalDataCache; -import unprotesting.com.github.data.ephemeral.data.AutosellData; -import unprotesting.com.github.data.persistent.Database; -import unprotesting.com.github.data.persistent.TimePeriod; -import unprotesting.com.github.economy.EconomyFunctions; -import unprotesting.com.github.events.async.AutosellProfitUpdateEvent; -import unprotesting.com.github.events.async.IpCheckEvent; -import unprotesting.com.github.events.async.LoanUpdateEvent; -import unprotesting.com.github.events.async.PriceUpdateEvent; -import unprotesting.com.github.events.async.SellPriceDifferenceUpdateEvent; -import unprotesting.com.github.events.sync.AutosellUpdateEvent; -import unprotesting.com.github.events.sync.JoinMessageEventHandler; -import unprotesting.com.github.events.sync.TutorialSendEvent; -import unprotesting.com.github.events.sync.UnlockUpdateEvent; -import unprotesting.com.github.localserver.LocalServer; -import unprotesting.com.github.util.UtilFunctions; - -/** - * The main class of AutoTune. - */ -@Getter -@Setter -public class Main extends JavaPlugin { - - @Getter - private static Main instance; - - private DataFiles dataFiles; - private Database database; - private LocalDataCache cache; - private IEssentials ess; - private String[] serverIPs; - private AutosellData autosellData; - public LocalServer localServer; - private boolean essentialsEnabled = false; - private boolean placeholderApi = false; - private MiniMessage mm; - - /** - * Called when the plugin is disabled. - */ - @Override - public void onDisable() { - - database.saveCacheToLastTP(); - - // Run a time period update to update the database before closing. - if (cache != null) { - updateTimePeriod(); - } - - } - - /** - * Called when the plugin is enabled. - */ - @Override - public void onEnable() { - - instance = this; - checkEconomy(); - getEssentials(); - setupDataFiles(); - mm = MiniMessage.miniMessage(); - UtilFunctions.setDf(new DecimalFormat(Config.getConfig().getNumberFormat())); - Level logLevel = Level.parse(Config.getConfig().getLogLevel()); - getLogger().setLevel(logLevel); - getLogger().info("Log level set to " + getLogger().getLevel().toString()); - new Messages(); - - Bukkit.getScheduler().runTaskAsynchronously(this, () -> - Bukkit.getPluginManager().callEvent(new IpCheckEvent(true))); - - database = new Database(); - cache = new LocalDataCache(); - setupCommands(); - setupEvents(); - localServer = new LocalServer(); - setAutosellData(new AutosellData()); - new Metrics(this, 9687); - - } - - /** - * Run a time period update. - */ - public void updateTimePeriod() { - - getLogger().config("Updating time period."); - new TimePeriod().addToMap(); - cache = new LocalDataCache(); - if (Config.getConfig().isWebServerEnabled()) { - getLogger().fine("Writing CSV file"); - CsvHandler.writeCsv(); - } - - - } - - /** - * Check that an economy plugin is installed. - */ - private void checkEconomy() { - - // Check if an economy plugin is installed and if it is enabled, if it is return. - if (EconomyFunctions.setupLocalEconomy(getServer())) { - getLogger().info("Found an economy plugin."); - return; - } - - getLogger().severe("No economy plugin found." - + " Auto-Tune requires Vault or a compatible economy plugin."); - - getServer().getPluginManager().disablePlugin(this); - return; - - } - - /** - * Setup all the data files. - */ - public void setupDataFiles() { - - dataFiles = new DataFiles(getDataFolder()); - - // Iterate through all the data files and setup them. - for (int i = 0; i < dataFiles.getFileNames().length; i++) { - if (!dataFiles.getFiles()[i].exists()) { - saveResource(dataFiles.getFileNames()[i], false); - } - } - - dataFiles.loadConfigs(); - - } - - /** - * Register all the commands. - */ - private void setupCommands() { - - getCommand("shop").setExecutor(new ShopCommand()); - getCommand("sell").setExecutor(new SellCommand()); - getCommand("trade").setExecutor(new TradeCommand()); - getCommand("gdp").setExecutor(new GdpCommand()); - getCommand("transactions").setExecutor(new TransactionsCommand()); - getCommand("loan").setExecutor(new LoanCommand()); - getCommand("autosell").setExecutor(new AutosellCommand()); - getCommand("at").setExecutor(new AutoTuneCommand()); - - } - - /** - * Register all the events. - */ - private void setupEvents() { - - // Asynchronous - Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> - Bukkit.getPluginManager().callEvent(new PriceUpdateEvent(true)), - Config.getConfig().getTimePeriod() * 1200, Config.getConfig().getTimePeriod() * 1200); - - Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> - Bukkit.getPluginManager().callEvent(new LoanUpdateEvent(true)), - Config.getConfig().getInterestRateUpdateRate(), - Config.getConfig().getInterestRateUpdateRate()); - - Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> - Bukkit.getPluginManager().callEvent(new SellPriceDifferenceUpdateEvent(true)), - Config.getConfig().getSellPriceVariationUpdatePeriod() * 1200, - Config.getConfig().getSellPriceVariationUpdatePeriod() * 1200); - - Bukkit.getScheduler().runTaskTimerAsynchronously(this, () -> - Bukkit.getPluginManager().callEvent(new AutosellProfitUpdateEvent(true)), - Config.getConfig().getAutoSellProfitUpdatePeriod(), - Config.getConfig().getAutoSellProfitUpdatePeriod()); - - // Synchronous - Bukkit.getScheduler().runTaskTimer(this, () -> - Bukkit.getPluginManager().callEvent(new AutosellUpdateEvent()), - Config.getConfig().getAutoSellUpdatePeriod(), Config.getConfig().getAutoSellUpdatePeriod()); - - Bukkit.getScheduler().runTaskTimer(this, () -> - Bukkit.getPluginManager().callEvent(new TutorialSendEvent()), - Config.getConfig().getTutorialMessagePeriod() * 20, - Config.getConfig().getTutorialMessagePeriod() * 20); - - Bukkit.getScheduler().runTaskTimer(this, () -> - Bukkit.getPluginManager().callEvent(new UnlockUpdateEvent()), 60, 60); - - Bukkit.getServer().getPluginManager().registerEvents(new JoinMessageEventHandler(), this); - - } - - /** - * Get the Essentials plugin. - */ - private void getEssentials() { - - Plugin plugin = Bukkit.getPluginManager().getPlugin("Essentials"); - - // If essentials is not installed, set essentialsEnabled to false and return. - if (plugin == null) { - setEssentialsEnabled(false); - getLogger().info("Essentials not found."); - return; - } - - setEssentialsEnabled(true); - setEss((IEssentials) plugin); - getLogger().info("Found Essentials."); - - } - -} diff --git a/src/main/java/unprotesting/com/github/commands/AutoTuneCommand.java b/src/main/java/unprotesting/com/github/commands/AutoTuneCommand.java deleted file mode 100644 index d3fe2b5..0000000 --- a/src/main/java/unprotesting/com/github/commands/AutoTuneCommand.java +++ /dev/null @@ -1,158 +0,0 @@ -package unprotesting.com.github.commands; - -import java.util.HashMap; -import java.util.Set; - -import net.kyori.adventure.text.Component; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; - -import unprotesting.com.github.Main; -import unprotesting.com.github.commands.util.CommandUtil; -import unprotesting.com.github.config.Config; -import unprotesting.com.github.data.ephemeral.data.MaxBuySellData; -import unprotesting.com.github.events.async.PriceUpdateEvent; - -public class AutoTuneCommand implements CommandExecutor { - - @Override - public boolean onCommand(CommandSender sender, Command command, String at, String[] args) { - - if (!CommandUtil.checkIfSenderPlayer(sender)) { - return true; - } - return interpretCommand(sender, args); - - } - - private boolean interpretCommand(CommandSender sender, String[] args) { - - Player player = CommandUtil.closeInventory(sender); - - if (!(player.hasPermission("at.admin"))) { - - CommandUtil.noPermission(player); - return true; - - } - - if (args.length == 0) { - return returnDefault(player); - } else if (args[0].equalsIgnoreCase("update") && args.length == 1) { - - player.sendMessage(ChatColor.GOLD + "Attempting to force Auto-Tune to update."); - - Bukkit.getScheduler().runTaskAsynchronously(Main.getInstance(), - () -> Bukkit.getPluginManager().callEvent(new PriceUpdateEvent(true))); - - player.sendMessage(ChatColor.GREEN + "Updated Auto-Tune time period."); - return true; - - } else if (args[0].equalsIgnoreCase("price") && args.length == 3) { - return changePrice(player, args[1], args[2]); - } else if (args[0].equalsIgnoreCase("reload") && args.length == 1) { - return reload(player); - } - - return returnDefault(player); - - } - - private boolean returnDefault(Player player) { - - player.sendMessage(ChatColor.GOLD + "<===== Welcome to Auto-Tune! =====>"); - - player.sendMessage(ChatColor.GOLD + "/at price " - + " | Change the price of an item."); - - player.sendMessage(ChatColor.GOLD + "/at reload | Reload all files (to update settings)."); - player.sendMessage(ChatColor.GOLD + "/at update | Force a price update."); - return true; - - } - - private boolean changePrice(Player player, String itemName, String newPrice) { - - Double price; - - if (newPrice == null) { - return false; - } - - try { - price = Double.parseDouble(newPrice); - } catch (NumberFormatException e) { - player.sendMessage(ChatColor.RED + "Incorrect number format."); - return true; - } catch (NullPointerException e) { - return false; - } - - itemName = itemName.toUpperCase(); - Component displayName = new ItemStack(Material.matchMaterial(itemName)).displayName(); - - if (Main.getInstance().getCache().getItems().containsKey(itemName)) { - - Main.getInstance().getCache().getItems().get(itemName).setPrice(price); - - player.sendMessage(ChatColor.GREEN + "Changed " + displayName - + " to " + Config.getConfig().getCurrencySymbol() + newPrice); - - return true; - - } else if (Main.getInstance().getCache().getEnchantments().containsKey(itemName)) { - - Main.getInstance().getCache().getEnchantments().get(itemName).setPrice(price); - - player.sendMessage(ChatColor.GREEN + "Changed " + displayName - + " to " + Config.getConfig().getCurrencySymbol() + newPrice); - - return true; - - } else { - - player.sendMessage(ChatColor.RED + itemName + " is not a valid input."); - return false; - - } - - } - - private boolean reload(Player player) { - - Main.getInstance().setupDataFiles(); - - ConfigurationSection config = Main.getInstance().getDataFiles() - .getShops().getConfigurationSection("shops"); - - Set set = config.getKeys(false); - - HashMap maxPurchases = new HashMap(); - - for (String key : set) { - - ConfigurationSection section = config.getConfigurationSection(key); - - MaxBuySellData maxBuySellData = new MaxBuySellData( - section.getInt("max-buy", 9999), - section.getInt("max-sell", 9999)); - - maxPurchases.put(key, maxBuySellData); - - } - - Main.getInstance().getCache().setMaxPurchases(maxPurchases); - player.sendMessage(ChatColor.GREEN + "Reload successful."); - return true; - - } - -} diff --git a/src/main/java/unprotesting/com/github/commands/AutoTuneShopFormat.java b/src/main/java/unprotesting/com/github/commands/AutoTuneShopFormat.java new file mode 100644 index 0000000..cf45df9 --- /dev/null +++ b/src/main/java/unprotesting/com/github/commands/AutoTuneShopFormat.java @@ -0,0 +1,285 @@ +package unprotesting.com.github.commands; + +import com.github.stefvanschie.inventoryframework.gui.GuiItem; +import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; +import com.github.stefvanschie.inventoryframework.pane.OutlinePane; +import com.github.stefvanschie.inventoryframework.pane.PaginatedPane; +import com.github.stefvanschie.inventoryframework.pane.Pane.Priority; +import com.github.stefvanschie.inventoryframework.pane.StaticPane; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextDecoration; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; + +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.command.CommandSender; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +import unprotesting.com.github.config.Config; +import unprotesting.com.github.data.EconomyDataUtil; +import unprotesting.com.github.data.Section; +import unprotesting.com.github.data.Shop; +import unprotesting.com.github.data.ShopUtil; +import unprotesting.com.github.util.Format; + +public abstract class AutoTuneShopFormat { + + private static OutlinePane background; + + protected boolean interpret(CommandSender sender, String[] args) { + + if (args.length > 1) { + return false; + } + + ChestGui gui = new ChestGui(6, "Shop"); + gui.setOnGlobalClick(event -> event.setCancelled(true)); + getBackground(gui); + + if (args.length == 0) { + gui.addPane(loadSectionsPane((Player) sender, gui)); + } + + if (args.length == 1) { + Section section = ShopUtil.getSection(args[0]); + if (section == null) { + Format.sendMessage((Player) sender, Config.get().getInvalidShopSection()); + return true; + } + gui.addPane(loadShopPane((Player) sender, gui, section)); + } + + gui.show((HumanEntity) sender); + return true; + } + + private StaticPane loadSectionsPane(Player player, ChestGui gui) { + StaticPane pane = new StaticPane(0, 0, 9, 6, Priority.HIGHEST); + + for (String sectionName : ShopUtil.getSectionNames()) { + Section section = ShopUtil.getSection(sectionName); + GuiItem item = new GuiItem(section.getItem(), event -> { + event.setCancelled(true); + gui.getPanes().clear(); + getBackground(gui); + gui.addPane(loadShopPane(player, gui, section)); + gui.addPane(getGdpPane(player, gui)); + gui.update(); + }); + pane.addItem(item, section.getPosX(), section.getPosY()); + } + + return pane; + } + + protected PaginatedPane loadShopPane(Player player, ChestGui gui, Section section) { + PaginatedPane pages = new PaginatedPane(0, 0, 9, 6, Priority.HIGHEST); + Map shops = section.getShops(); + List shopNames = new ArrayList<>(shops.keySet()); + shopNames.sort((s1, s2) -> s1.compareToIgnoreCase(s2)); + int page = 0; + List itemsOnPage = new ArrayList<>(); + + for (String shopName : shopNames) { + ItemStack item = shops.get(shopName).isEnchantment() ? new ItemStack(Material.ENCHANTED_BOOK) + : new ItemStack(Material.matchMaterial(shopName)); + if (shops.get(shopName).isEnchantment()) { + Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(shopName)); + item.editMeta(meta -> meta.displayName(enchantment.displayName(1))); + } + item.lore(applyLore(player, shopName, 1)); + itemsOnPage.add(new GuiItem(item, event -> { + event.setCancelled(true); + doShop(event.getWhoClicked(), gui, shopName); + gui.update(); + })); + + if (itemsOnPage.size() == 28 || itemsOnPage.size() + page * 28 == shops.size()) { + OutlinePane pane = new OutlinePane(1, 1, 7, 4, Priority.HIGHEST); + + for (GuiItem guiItem : itemsOnPage) { + pane.addItem(guiItem); + } + + if (page != 0) { + pages.addPane(page, getPageSelector(gui, pages, page - 1, 0)); + } + + if (itemsOnPage.size() == 28 && itemsOnPage.size() + page * 28 != shops.size()) { + pages.addPane(page, getPageSelector(gui, pages, page + 1, 8)); + } + + pages.addPane(page, pane); + pages.addPane(page, getBackToSectionsPane(player, gui)); + page++; + itemsOnPage.clear(); + } + } + + return pages; + } + + private StaticPane getBackToSectionsPane(Player player, ChestGui gui) { + StaticPane pane = new StaticPane(0, 0, 1, 1, Priority.HIGHEST); + ItemStack item = new ItemStack(Material.ARROW); + item.editMeta(meta -> + meta.displayName(Format.getComponent("Back to menu").asComponent())); + pane.addItem(new GuiItem(item, event -> { + event.setCancelled(true); + gui.getPanes().clear(); + getBackground(gui); + gui.addPane(loadSectionsPane(player, gui)); + gui.addPane(getGdpPane(player, gui)); + gui.update(); + }), 0, 0); + return pane; + } + + private StaticPane getPageSelector(ChestGui gui, PaginatedPane pages, int page, int x) { + StaticPane pane = new StaticPane(x, 5, 1, 1, Priority.HIGHEST); + ItemStack item = new ItemStack(Material.ARROW); + item.editMeta(meta -> + meta.displayName(Format.getComponent( + "Go to page " + page + 1).asComponent())); + pane.addItem(new GuiItem(item, event -> { + event.setCancelled(true); + pages.setPage(page); + gui.update(); + }), 0, 0); + return pane; + } + + protected StaticPane getBackToShop(Player player, ChestGui gui, String sectionName) { + StaticPane pane = new StaticPane(0, 0, 1, 1, Priority.HIGHEST); + ItemStack item = new ItemStack(Material.ARROW); + Section section = ShopUtil.getSection(sectionName); + item.editMeta(meta -> + meta.displayName(section.getItem().displayName())); + pane.addItem(new GuiItem(item, event -> { + event.setCancelled(true); + gui.getPanes().clear(); + getBackground(gui); + gui.addPane(loadShopPane(player, gui, section)); + gui.addPane(getGdpPane(player, gui)); + gui.update(); + }), 0, 0); + return pane; + } + + protected StaticPane getGdpPane(Player player, ChestGui gui) { + ItemStack item = new ItemStack(Material.GOLD_INGOT); + TagResolver r = getGdpTagResolver(); + item.editMeta(meta -> + Format.getComponent(Config.get().getShopGdpLore().get(0), r)); + List lore = new ArrayList<>(); + + for (int i = 1; i < Config.get().getShopGdpLore().size(); i++) { + lore.add(Format.getComponent(Config.get().getShopGdpLore().get(i), r)); + } + + item.lore(lore); + StaticPane pane = new StaticPane(8, 0, 1, 1, Priority.HIGHEST); + pane.addItem(new GuiItem(item, event -> { + event.setCancelled(true); + }), 0, 0); + return pane; + } + + protected static void getBackground(ChestGui gui) { + + if (background != null) { + gui.addPane(background); + return; + } + + GuiItem item = getBackgroundItem(); + + if (item == null) { + return; + } + + OutlinePane pane = new OutlinePane(0, 0, 9, 6, Priority.LOWEST); + pane.addItem(item); + pane.setRepeat(true); + gui.addPane(pane); + background = pane; + } + + protected static GuiItem getBackgroundItem() { + Material material = Material.matchMaterial(Config.get().getBackground()); + + if (material == null) { + return null; + } + + ItemStack item = new ItemStack(material); + item.editMeta(meta -> + meta.displayName(Component.text("|", Style.style(TextDecoration.OBFUSCATED)))); + return new GuiItem(item); + } + + protected TagResolver getGdpTagResolver() { + TagResolver.Builder builder = TagResolver.builder(); + double gdp = EconomyDataUtil.getGdp(); + double balance = EconomyDataUtil.getBalance(); + int capita = EconomyDataUtil.getPopulation(); + double loss = EconomyDataUtil.getLoss(); + double debt = EconomyDataUtil.getDebt(); + double inflation = EconomyDataUtil.getInflation(); + builder.resolver(Placeholder.parsed("gdp", Format.currency(gdp))); + builder.resolver(Placeholder.parsed("balance", Format.currency(balance))); + builder.resolver(Placeholder.parsed("population", Format.number(capita))); + builder.resolver(Placeholder.parsed("loss", Format.currency(loss))); + builder.resolver(Placeholder.parsed("debt", Format.currency(debt))); + builder.resolver(Placeholder.parsed("inflation", Format.percent(inflation))); + builder.resolver(Placeholder.parsed("gdp-per-capita", Format.currency(gdp / capita))); + builder.resolver(Placeholder.parsed("balance-per-capita", Format.currency(balance / capita))); + builder.resolver(Placeholder.parsed("loss-per-capita", Format.currency(loss / capita))); + builder.resolver(Placeholder.parsed("debt-per-capita", Format.currency(debt / capita))); + return builder.build(); + } + + protected List getLore(Player player, String shopName, List lore, int amount) { + Shop shop = ShopUtil.getShop(shopName); + boolean autosellSetting = false; + if (Config.get().getAutosell().get(player.getUniqueId() + "." + shopName) != null) { + autosellSetting = Config.get().getAutosell().getBoolean( + player.getUniqueId() + "." + shopName); + } + List loreComponents = new ArrayList<>(); + TagResolver resolver = TagResolver.resolver( + Placeholder.parsed("price", Format.currency(shop.getPrice())), + Placeholder.parsed("sell-price", Format.currency(shop.getSellPrice())), + Placeholder.parsed("total-price", Format.currency(amount * shop.getPrice())), + Placeholder.parsed("total-sell-price", Format.currency(amount * shop.getSellPrice())), + Placeholder.parsed("amount", Format.number(amount)), + Placeholder.parsed("buys-left", Format.number(ShopUtil.getBuysLeft(player, shopName))), + Placeholder.parsed("sells-left", Format.number(ShopUtil.getSellsLeft(player, shopName))), + Placeholder.parsed("max-buys", Format.number(shop.getMaxBuys())), + Placeholder.parsed("max-sells", Format.number(shop.getMaxSells())), + Placeholder.parsed("change", Format.percent(shop.getChange())), + Placeholder.parsed("collect-first-setting", shop.getSetting().getSetting().toString()), + Placeholder.parsed("autosell-setting", autosellSetting ? "enabled" : "disabled")); + + for (String line : lore) { + loreComponents.add(Format.getComponent(line, resolver)); + } + + return loreComponents; + } + + protected abstract void doShop(HumanEntity player, ChestGui gui, String shopName); + + protected abstract List applyLore(Player player, String shopName, int amount); + +} diff --git a/src/main/java/unprotesting/com/github/commands/AutosellCommand.java b/src/main/java/unprotesting/com/github/commands/AutosellCommand.java index c560c91..3365dab 100644 --- a/src/main/java/unprotesting/com/github/commands/AutosellCommand.java +++ b/src/main/java/unprotesting/com/github/commands/AutosellCommand.java @@ -1,147 +1,65 @@ package unprotesting.com.github.commands; -import com.github.stefvanschie.inventoryframework.gui.GuiItem; -import com.github.stefvanschie.inventoryframework.pane.StaticPane; +import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; -import java.text.DecimalFormat; -import java.util.Arrays; +import java.util.List; +import java.util.UUID; import net.kyori.adventure.text.Component; -import org.bukkit.ChatColor; -import org.bukkit.Material; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; -import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; -import unprotesting.com.github.Main; -import unprotesting.com.github.commands.objects.Section; -import unprotesting.com.github.commands.objects.SectionItemData; -import unprotesting.com.github.commands.util.CommandUtil; -import unprotesting.com.github.commands.util.ShopFormat; import unprotesting.com.github.config.Config; +import unprotesting.com.github.data.Section; +import unprotesting.com.github.data.Shop; +import unprotesting.com.github.data.ShopUtil; +import unprotesting.com.github.util.Format; -public class AutosellCommand extends ShopFormat implements CommandExecutor { +public class AutosellCommand extends AutoTuneShopFormat implements CommandExecutor { + @Override - public boolean onCommand(CommandSender sender, Command command, String autosell, String[] args) { - - if (!CommandUtil.checkIfSenderPlayer(sender)) { - return true; - } - - return interpretCommand(sender, args, "at.autosell"); - - } - - /** - * Loads the sections panel for the autosell command. - */ - public StaticPane loadSectionsPane(CommandSender sender, int lines) { - StaticPane navigationPane = new StaticPane(0, 0, 9, lines); - - for (Section section : Main.getInstance().getCache().getSections()) { - - if (section.isEnchantmentSection()) { - continue; - } - - ItemStack item = new ItemStack(section.getImage()); - ItemMeta meta = item.getItemMeta(); - meta.displayName(Component.text(section.getDisplayName())); - int posX = section.getPosition() % 9; - int posY = section.getPosition() / 9; - - meta.lore(Arrays.asList(new Component[] { Component.text( - ChatColor.WHITE + "Click to change " - + section.getName() + " autosell settings.")})); - - item.setItemMeta(meta); - - GuiItem guiItem = new GuiItem(item, event -> { - - event.setCancelled(true); - loadShopPane(sender, section); - - }); - - navigationPane.addItem(guiItem, posX, posY); - - } - - return navigationPane; - - } - - /** - * Get a Gui Item for a given section, itemName, and display name. - * @param section The section to get the item for. - * @param itemInput The item data to get the item for. - * @param sender The sender to send messages to. - * @return The Gui Item. - */ - public GuiItem getGuiItem(Section section, SectionItemData itemInput, CommandSender sender) { - - Player player = (Player) sender; - DecimalFormat df = new DecimalFormat(Config.getConfig().getNumberFormat()); - ItemStack item = new ItemStack(Material.matchMaterial(itemInput.getName())); - ItemMeta meta = item.getItemMeta(); - String lore = "Click to turn on auto-selling!"; - boolean setting = CommandUtil.getPlayerAutoSellSetting(player, item.getType().toString()); - - if (setting) { - lore = ChatColor.GREEN + "Click to turn off auto-selling!"; + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, + @NotNull String label, @NotNull String[] args) { + + if (sender instanceof Player) { + return interpret((Player) sender, args); } - meta.setLore(Arrays.asList(new String[] { lore, ChatColor.WHITE + "Sell-Price: " - + ChatColor.GOLD + Config.getConfig().getCurrencySymbol() - + df.format(Main.getInstance().getCache().getItemPrice( - item.getType().toString(), true)) })); - - item.setItemMeta(meta); - - GuiItem guiItem = new GuiItem(item, event -> { - event.setCancelled(true); - changePlayerAutoSellSetting(player, item.getType().toString()); - player.getOpenInventory().close(); - loadShopPane(sender, section); - }); - - return guiItem; - + Format.sendMessage(sender, "You must be a player to use this command."); + return true; } - private void changePlayerAutoSellSetting(Player player, String item) { - - String uuid = player.getUniqueId().toString(); - YamlConfiguration config = Main.getInstance().getDataFiles().getPlayerData(); - - if (!config.contains(uuid + ".autosell")) { - - config.createSection(uuid + ".autosell"); - config.set(uuid + ".autosell." + item, true); - Main.getInstance().getDataFiles().setPlayerData(config); - return; - - } else if (!config.contains(uuid + ".autosell." + item)) { - - config.createSection(uuid + ".autosell." + item); - config.set(uuid + ".autosell." + item, true); - Main.getInstance().getDataFiles().setPlayerData(config); - return; - + @Override + protected void doShop(HumanEntity player, ChestGui gui, String shopName) { + Shop shop = ShopUtil.getShop(shopName); + Player user = (Player) player; + UUID uuid = user.getUniqueId(); + ConfigurationSection autosell = Config.get().getAutosell(); + if (autosell.contains(uuid + "." + shopName)) { + boolean value = autosell.getBoolean(uuid + "." + shopName); + autosell.set(uuid + "." + shopName, !value); } else { - - boolean setting = false; - setting = config.getBoolean(uuid + ".autosell." + item, false); - config.set(uuid + ".autosell." + item, !setting); - + autosell.set(uuid + "." + shopName, true); } - + Config.get().setAutosell(autosell); + Section section = ShopUtil.getSection(shop.getSection()); + gui.getPanes().clear(); + getBackground(gui); + gui.addPane(loadShopPane(user, gui, section)); + gui.addPane(getGdpPane(user, gui)); + gui.update(); } + @Override + protected List applyLore(Player player, String shopName, int amount) { + return getLore(player, shopName, Config.get().getAutosellLore(), amount); + } + } diff --git a/src/main/java/unprotesting/com/github/commands/GdpCommand.java b/src/main/java/unprotesting/com/github/commands/GdpCommand.java deleted file mode 100644 index f637636..0000000 --- a/src/main/java/unprotesting/com/github/commands/GdpCommand.java +++ /dev/null @@ -1,211 +0,0 @@ -package unprotesting.com.github.commands; - -import com.github.stefvanschie.inventoryframework.gui.GuiItem; -import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; -import com.github.stefvanschie.inventoryframework.pane.StaticPane; - -import java.text.DecimalFormat; -import java.util.Arrays; - -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.HumanEntity; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import unprotesting.com.github.Main; -import unprotesting.com.github.commands.util.CommandUtil; -import unprotesting.com.github.config.Config; - -public class GdpCommand implements CommandExecutor { - - @Override - public boolean onCommand(CommandSender sender, Command command, String gdp, String[] args) { - - if (!CommandUtil.checkIfSenderPlayer(sender)) { - return true; - } - - return interpretCommand(sender, args); - } - - private boolean interpretCommand(CommandSender sender, String[] args) { - Player player = CommandUtil.closeInventory(sender); - - if (!(player.hasPermission("at.gdp") || player.hasPermission("at.admin"))) { - - CommandUtil.noPermission(player); - return true; - - } - - openGdpGui(sender); - return true; - - } - - private void openGdpGui(CommandSender sender) { - - CommandUtil.closeInventory(sender); - StaticPane pane = new StaticPane(9, 5); - Main.getInstance().getCache().getGdpData().updateBalance(); - Main.getInstance().getCache().getGdpData().updateDebt(); - pane.addItem(getGdpGuiItem(), 3, 1); - pane.addItem(getBalanceGuiItem(), 5, 1); - pane.addItem(getDebtGuiItem(), 2, 2); - pane.addItem(getLossGuiItem(), 4, 2); - pane.addItem(getInflationGuiItem(), 6, 2); - ChestGui gui = new ChestGui(5, "GDP and Economy Info"); - gui.addPane(pane); - gui.show((HumanEntity) sender); - - } - - private GuiItem getGdpGuiItem() { - - DecimalFormat df = new DecimalFormat(Config.getConfig().getNumberFormat()); - ItemStack item = new ItemStack(Material.DIAMOND); - ItemMeta meta = item.getItemMeta(); - double gdp = Main.getInstance().getCache().getGdpData().getGdp(); - double gdpPerCapita = gdp / Main.getInstance().getCache().getGdpData().getPlayerCount(); - meta.setDisplayName(ChatColor.AQUA + "GDP"); - meta.setLore(Arrays.asList(new String[] { - - ChatColor.GOLD + "-> GDP: " + Config.getConfig().getCurrencySymbol() + df.format(gdp) + ".", - ChatColor.GOLD + "-> GDP per Capita: " - + Config.getConfig().getCurrencySymbol() + df.format(gdpPerCapita) + ".", - ChatColor.WHITE + "-> GDP is the total value of all", - ChatColor.WHITE + "transactions on the server.", - ChatColor.WHITE + "-> GDP per Capita is the average GDP a ", - ChatColor.WHITE + "player has contributed to the server." - - })); - - item.setItemMeta(meta); - - GuiItem guiItem = new GuiItem(item, event -> { - event.setCancelled(true); - }); - - return guiItem; - } - - private GuiItem getBalanceGuiItem() { - - DecimalFormat df = new DecimalFormat(Config.getConfig().getNumberFormat()); - ItemStack item = new ItemStack(Material.GOLD_INGOT); - ItemMeta meta = item.getItemMeta(); - double bal = Main.getInstance().getCache().getGdpData().getBalance(); - double balPerCapita = bal / Main.getInstance().getCache().getGdpData().getPlayerCount(); - meta.setDisplayName(ChatColor.AQUA + "Balance"); - meta.setLore(Arrays.asList(new String[] { - - ChatColor.GOLD + "-> Balance: " - + Config.getConfig().getCurrencySymbol() + df.format(bal) + ".", - ChatColor.GOLD + "-> Balance per Capita: " - + Config.getConfig().getCurrencySymbol() + df.format(balPerCapita) + ".", - ChatColor.WHITE + "-> Balance is the total server balance", - ChatColor.WHITE + "(all player balances combined).", - ChatColor.WHITE + "-> Balance per Capita is the average", - ChatColor.WHITE + "players balance." - - })); - - item.setItemMeta(meta); - - GuiItem guiItem = new GuiItem(item, event -> { - event.setCancelled(true); - }); - - return guiItem; - } - - private GuiItem getDebtGuiItem() { - - DecimalFormat df = new DecimalFormat(Config.getConfig().getNumberFormat()); - ItemStack item = new ItemStack(Material.EMERALD); - ItemMeta meta = item.getItemMeta(); - double debt = Main.getInstance().getCache().getGdpData().getDebt(); - double debtPerCapita = debt / Main.getInstance().getCache().getGdpData().getPlayerCount(); - meta.setDisplayName(ChatColor.AQUA + "Debt"); - meta.setLore(Arrays.asList(new String[] { - - ChatColor.GOLD + "-> Debt: " - + Config.getConfig().getCurrencySymbol() + df.format(debt) + ".", - ChatColor.GOLD + "-> Debt per Capita: " - + Config.getConfig().getCurrencySymbol() + df.format(debtPerCapita) + ".", - ChatColor.WHITE + "-> Debt is the total server debt.", - ChatColor.WHITE + "-> Debt per Capita is the average", - ChatColor.WHITE + "debt of each player." - - })); - - item.setItemMeta(meta); - - GuiItem guiItem = new GuiItem(item, event -> { - event.setCancelled(true); - }); - - return guiItem; - } - - private GuiItem getLossGuiItem() { - - DecimalFormat df = new DecimalFormat(Config.getConfig().getNumberFormat()); - ItemStack item = new ItemStack(Material.FLINT); - ItemMeta meta = item.getItemMeta(); - double loss = Main.getInstance().getCache().getGdpData().getLoss(); - double lossPerCapita = loss / Main.getInstance().getCache().getGdpData().getPlayerCount(); - meta.setDisplayName(ChatColor.AQUA + "Loss"); - meta.setLore(Arrays.asList(new String[] { - - ChatColor.GOLD + "-> Loss: " - + Config.getConfig().getCurrencySymbol() + df.format(loss) + ".", - ChatColor.GOLD + "-> Loss per Capita: " - + Config.getConfig().getCurrencySymbol() + df.format(lossPerCapita) + ".", - ChatColor.WHITE + "-> Loss is the total balance", - ChatColor.WHITE + "lost to fees.", - ChatColor.WHITE + "-> Loss per Capita is the average", - ChatColor.WHITE + "loss per player." - - })); - - item.setItemMeta(meta); - - GuiItem guiItem = new GuiItem(item, event -> { - event.setCancelled(true); - }); - - return guiItem; - } - - private GuiItem getInflationGuiItem() { - - DecimalFormat df = new DecimalFormat(Config.getConfig().getNumberFormat()); - ItemStack item = new ItemStack(Material.BAMBOO); - ItemMeta meta = item.getItemMeta(); - double inflation = Main.getInstance().getCache().getGdpData().getInflation(); - meta.setDisplayName(ChatColor.AQUA + "Inflation"); - - meta.setLore(Arrays.asList(new String[] { - - ChatColor.GOLD + "-> Inflation: " + df.format(inflation) + "%.", - ChatColor.WHITE + "-> Inflation is the average change", - ChatColor.WHITE + "in prices in the last 24 hours.", - - })); - - item.setItemMeta(meta); - - GuiItem guiItem = new GuiItem(item, event -> { - event.setCancelled(true); - }); - - return guiItem; - } - -} diff --git a/src/main/java/unprotesting/com/github/commands/LoanCommand.java b/src/main/java/unprotesting/com/github/commands/LoanCommand.java index a5b7da4..875efdb 100644 --- a/src/main/java/unprotesting/com/github/commands/LoanCommand.java +++ b/src/main/java/unprotesting/com/github/commands/LoanCommand.java @@ -1,191 +1,105 @@ package unprotesting.com.github.commands; -import com.github.stefvanschie.inventoryframework.gui.GuiItem; -import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; -import com.github.stefvanschie.inventoryframework.pane.OutlinePane; -import com.github.stefvanschie.inventoryframework.pane.PaginatedPane; - -import java.text.DecimalFormat; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import java.util.Map; import java.util.UUID; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; -import unprotesting.com.github.Main; -import unprotesting.com.github.commands.util.CommandUtil; import unprotesting.com.github.config.Config; -import unprotesting.com.github.data.ephemeral.data.LoanData; -import unprotesting.com.github.economy.EconomyFunctions; +import unprotesting.com.github.data.Database; +import unprotesting.com.github.data.Loan; +import unprotesting.com.github.util.EconomyUtil; +import unprotesting.com.github.util.Format; public class LoanCommand implements CommandExecutor { - private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - @Override - public boolean onCommand(CommandSender sender, Command command, String loan, String[] args) { - - if (!CommandUtil.checkIfSenderPlayer(sender)) { - return true; - } - - return interpretCommand(sender, args); - } - - @Deprecated - private boolean interpretCommand(CommandSender sender, String[] args) { + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, + @NotNull String label, @NotNull String[] args) { - Player player = CommandUtil.closeInventory(sender); - - if (!(player.hasPermission("at.loan") || player.hasPermission("at.admin"))) { - - CommandUtil.noPermission(player); + if (!(sender instanceof Player)) { + Format.sendMessage(sender, "This command is for players only."); return true; - } - ChestGui gui = new ChestGui(6, "Loans"); - PaginatedPane pages = new PaginatedPane(0, 0, 9, 6); - List loans = Main.getInstance().getCache().getLoans(); - List panes = new ArrayList(); - List items; - String uuid = player.getUniqueId().toString(); - - if (args.length < 1) { - - if (!player.hasPermission("at.loan.other") && !player.hasPermission("at.admin")) { - items = getGuiItemsFromLoans(loans, uuid); - } else { - items = getGuiItemsFromLoans(loans, null); - } - - } else if (args[0].equals("-p")) { - - if (args[1].equals(player.getName())) { - items = getGuiItemsFromLoans(loans, uuid); - } else if (!args[1].equals(player.getName()) - && (!player.hasPermission("at.loan.other") && !player.hasPermission("at.admin"))) { - - CommandUtil.noPermission(player); - return true; - - } else { - - OfflinePlayer offPlayer = Bukkit.getOfflinePlayer(args[1]); - items = getGuiItemsFromLoans(loans, offPlayer.getUniqueId().toString()); - + Player player = (Player) sender; + if (args.length == 0) { + getTotalLoans(player); + Format.sendMessage(player, "Usage: /loan /pay"); + } else if (args[0].equalsIgnoreCase("pay") || args[0].equalsIgnoreCase("payback")) { + for (Map.Entry entry : Database.get().getLoans().entrySet()) { + Loan loan = entry.getValue(); + if (loan.getPlayer().equals(player.getUniqueId())) { + + if (loan.isPaid()) { + continue; + } + + if (loan.payBack()) { + Format.sendMessage(player, "You have paid back your loan of " + + Format.currency(loan.getValue()) + "."); + } else { + Format.sendMessage(player, "You do not have enough money to pay back your loan."); + } + Database.get().updateLoan(entry.getKey(), loan); + + } } - } else { - - double loanAmount; - + double value = 0; try { - loanAmount = Double.parseDouble(args[0]); + value = Double.parseDouble(args[0]); } catch (NumberFormatException e) { - return false; + Format.sendMessage(player, "Invalid amount."); + return true; } - if (loanAmount < 0) { - - player.sendMessage(ChatColor.RED - + "Loan amount must be greater than " + Config.getConfig().getCurrencySymbol() - + "0.0 to take out a loan."); - + if (value <= 0) { + Format.sendMessage(player, "Invalid amount."); return true; } - double bal = EconomyFunctions.getEconomy().getBalance(player); - - if (bal - loanAmount < Config.getConfig().getMaxDebt()) { - - if (bal < Config.getConfig().getMaxDebt()) { - - player.sendMessage(ChatColor.RED + "Your balance must be more than " - + Config.getConfig().getCurrencySymbol() + Config.getConfig().getMaxDebt() - + " to take out a loan."); - - return true; - } - - player.sendMessage(ChatColor.RED + "Your balance minus your loans cannot be less than " - + Config.getConfig().getCurrencySymbol() + Config.getConfig().getMaxDebt() + "."); - + if (EconomyUtil.getEconomy().getBalance(player) + <= value + value * 0.05 * Config.get().getInterest()) { + Format.sendMessage(player, "You do not have enough money."); return true; } - - EconomyFunctions.getEconomy().depositPlayer(player, loanAmount); - - Main.getInstance().getCache().addLoan( - loanAmount, Config.getConfig().getInterestRate(), player); - - return true; - + + double base = value; + value += value * 0.01 * Config.get().getInterest(); + Loan loan = Loan.builder() + .value(value) + .base(base) + .player(player.getUniqueId()) + .paid(false) + .build(); + Database.get().getLoans().put(System.currentTimeMillis(), loan); + EconomyUtil.getEconomy().depositPlayer(player, base); + getTotalLoans(player); } - - CommandUtil.loadGuiItemsIntoPane(items, gui, pages, panes, - Material.GRAY_STAINED_GLASS_PANE, sender); - return true; } - private List getGuiItemsFromLoans(List loans, String uuid) { + private void getTotalLoans(Player player) { + UUID uuid = player.getUniqueId(); + double total = 0; - List output = new ArrayList(); - Collections.sort(loans); - DecimalFormat df = new DecimalFormat(Config.getConfig().getNumberFormat()); + for (Loan loan : Database.get().getLoans().values()) { + if (loan.getPlayer().equals(uuid)) { - for (LoanData data : loans) { + if (loan.isPaid()) { + continue; + } - if (uuid != null && !data.getPlayer().equals(uuid)) { - continue; + total += loan.getValue(); } - - ItemStack item = new ItemStack(Material.GREEN_STAINED_GLASS_PANE); - ItemMeta meta = item.getItemMeta(); - OfflinePlayer player = Bukkit.getPlayer(UUID.fromString(data.getPlayer())); - - meta.setDisplayName(ChatColor.GREEN - + Config.getConfig().getCurrencySymbol() + df.format(data.getValue())); - - meta.setLore(Arrays.asList(new String[] { - - ChatColor.WHITE + "Player: " + ChatColor.GOLD + player.getName(), - - ChatColor.WHITE + "Interest Rate: " + ChatColor.GOLD + data.getInterestRate() - + "% per " + df.format( - Config.getConfig().getInterestRateUpdateRate() / 1200) + "min has been created.", - - ChatColor.WHITE + "Date: " + ChatColor.GOLD + data.getDate().format(formatter), - ChatColor.GREEN + "Click to pay-back loan!" - - })); - - item.setItemMeta(meta); - - GuiItem guiItem = new GuiItem(item, event -> { - - data.payBackLoan(); - event.setCancelled(true); - - }); - - output.add(guiItem); } - return output; + Format.sendMessage(player, "You have " + Format.currency(total) + " in loans."); } - + } diff --git a/src/main/java/unprotesting/com/github/commands/SellCommand.java b/src/main/java/unprotesting/com/github/commands/SellCommand.java index 8dde67b..2f88f69 100644 --- a/src/main/java/unprotesting/com/github/commands/SellCommand.java +++ b/src/main/java/unprotesting/com/github/commands/SellCommand.java @@ -8,59 +8,39 @@ import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import org.jetbrains.annotations.NotNull; -import unprotesting.com.github.commands.util.CommandUtil; -import unprotesting.com.github.commands.util.FunctionsUtil; +import unprotesting.com.github.data.PurchaseUtil; +import unprotesting.com.github.util.Format; public class SellCommand implements CommandExecutor { @Override - public boolean onCommand(CommandSender sender, Command command, String sell, String[] args) { - - if (!CommandUtil.checkIfSenderPlayer(sender)) { - return true; - } - - return interpretCommand(sender); - - } - - private boolean interpretCommand(CommandSender sender) { - - Player player = CommandUtil.closeInventory(sender); - - if (!(player.hasPermission("at.sell") || player.hasPermission("at.admin"))) { - - CommandUtil.noPermission(player); - return true; - + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, + @NotNull String label, @NotNull String[] args) { + + if (sender instanceof Player) { + return interpret(sender); } - setupSellGui(sender); + Format.sendMessage(sender, "You must be a player to use this command."); return true; - } - private void setupSellGui(CommandSender sender) { - - Player player = CommandUtil.closeInventory(sender); + private boolean interpret(CommandSender sender) { + Player player = (Player) sender; + player.getOpenInventory().close(); ChestGui gui = new ChestGui(5, "Sell Panel"); - gui.setOnClose(event -> { - - for (ItemStack item : gui.getInventory().getStorageContents()) { - + for (ItemStack item : gui.getInventory().getContents()) { if (item == null) { continue; } - - FunctionsUtil.sellCustomItem(player, item, false); + PurchaseUtil.sellItemStack(item, player); } - }); - gui.show((HumanEntity) sender); - + return true; } } diff --git a/src/main/java/unprotesting/com/github/commands/ShopCommand.java b/src/main/java/unprotesting/com/github/commands/ShopCommand.java index e890522..191730d 100644 --- a/src/main/java/unprotesting/com/github/commands/ShopCommand.java +++ b/src/main/java/unprotesting/com/github/commands/ShopCommand.java @@ -3,311 +3,125 @@ import com.github.stefvanschie.inventoryframework.gui.GuiItem; import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; import com.github.stefvanschie.inventoryframework.pane.OutlinePane; -import com.github.stefvanschie.inventoryframework.pane.StaticPane; +import com.github.stefvanschie.inventoryframework.pane.Pane.Priority; -import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import net.kyori.adventure.text.Component; -import org.bukkit.ChatColor; import org.bukkit.Material; +import org.bukkit.NamespacedKey; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; +import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.HumanEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; +import org.jetbrains.annotations.NotNull; -import unprotesting.com.github.Main; -import unprotesting.com.github.commands.objects.Section; -import unprotesting.com.github.commands.objects.SectionItemData; -import unprotesting.com.github.commands.util.CommandUtil; -import unprotesting.com.github.commands.util.FunctionsUtil; -import unprotesting.com.github.commands.util.ShopFormat; import unprotesting.com.github.config.Config; +import unprotesting.com.github.data.PurchaseUtil; +import unprotesting.com.github.data.Shop; +import unprotesting.com.github.data.ShopUtil; +import unprotesting.com.github.util.Format; -public class ShopCommand extends ShopFormat implements CommandExecutor { +public class ShopCommand extends AutoTuneShopFormat implements CommandExecutor { - private Integer[] amounts = { 1, 2, 4, 8, 16, 32, 64 }; + private static final int[] AMOUNTS = {1, 2, 4, 8, 16, 32, 64}; + private static final int[] ENCHANTMENT_AMOUNTS = {1, 2, 3, 4, 5}; @Override - public boolean onCommand(CommandSender sender, Command command, String shop, String[] args) { - if (!CommandUtil.checkIfSenderPlayer(sender)) { - return true; - } - return interpretCommand((Player) sender, args, "at.shop"); - } - - public StaticPane loadSectionsPane(CommandSender sender, int lines) { - - StaticPane navigationPane = new StaticPane(0, 0, 9, lines); - for (Section section : Main.getInstance().getCache().getSections()) { - - if (section.isEnchantmentSection() && !Config.getConfig().isEnableEnchantments()) { - continue; - } - - ItemStack item = new ItemStack(section.getImage()); - ItemMeta meta = item.getItemMeta(); - meta.setDisplayName(section.getDisplayName()); - - meta.setLore(Arrays.asList(new String[] { - ChatColor.WHITE + "Click to enter " + section.getName() + " shop" })); - - item.setItemMeta(meta); - - GuiItem guiItem = new GuiItem(item, event -> { - - event.setCancelled(true); - loadShopPane(sender, section); - - }); - - navigationPane.addItem(guiItem, section.getPosition() % 9, section.getPosition() / 9); - } - - return navigationPane; - } - - public GuiItem getGuiItem(Section section, SectionItemData itemInput, CommandSender sender) { - - if (section.isEnchantmentSection() && !Config.getConfig().isEnableEnchantments()) { - return null; - } - - DecimalFormat df = new DecimalFormat(Config.getConfig().getNumberFormat()); - ItemStack item = new ItemStack(Material.BARRIER); - - try { - if (section.isEnchantmentSection()) { - item = new ItemStack(Material.ENCHANTED_BOOK); - } - if (!section.isEnchantmentSection()) { - item = new ItemStack(Material.matchMaterial(itemInput.getName())); - } - } catch (NullPointerException e) { - - Main.getInstance().getLogger().severe("Could not find item " - + itemInput.getName() + " in section " + section.getName()); - - return null; - - } - - List list = new ArrayList(); - Player player = (Player) sender; - - list.add(ChatColor.GREEN + Config.getConfig().getCurrencySymbol() - + df.format(Main.getInstance().getCache().getItemPrice(itemInput.getName(), false))); - - if (section.isEnchantmentSection()) { - - list.clear(); - ItemMeta meta = item.getItemMeta(); - meta.displayName(itemInput.getDisplayName()); - item.setItemMeta(meta); - - list.add(ChatColor.GREEN + Config.getConfig().getCurrencySymbol() - + df.format(getEnchantmentPriceWithHeld(itemInput.getName(), player))); - - } - - list.add(Main.getInstance().getCache().getChangeString(itemInput.getName())); - - if (section.isEnchantmentSection()) { - - list.add(ChatColor.YELLOW + "Ratio: " + df.format( - Main.getInstance().getCache().getEnchantmentRatio(itemInput.getName()))); - - list.add(ChatColor.YELLOW + "Price: " + Config.getConfig().getCurrencySymbol() - + df.format(Main.getInstance().getCache().getEnchantmentPrice( - itemInput.getName(), false))); + public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, + @NotNull String label, @NotNull String[] args) { + if (sender instanceof Player) { + return interpret((Player) sender, args); } - if (!Config.getConfig().isDisableMaxBuysSells()) { - - int buysLeft = Main.getInstance().getCache().getPurchasesLeft( - itemInput.getName(), player, true); - - int sellsLeft = Main.getInstance().getCache().getPurchasesLeft( - itemInput.getName(), player, false); - - if (buysLeft != 99999 && sellsLeft != 99999) { - - list.add(ChatColor.WHITE + "Remaining Buys: " + ChatColor.GRAY - + Main.getInstance().getCache().getPurchasesLeft(itemInput.getName(), player, true)); - - list.add(ChatColor.WHITE + "Remaining Sells: " + ChatColor.GRAY - + Main.getInstance().getCache().getPurchasesLeft(itemInput.getName(), player, false)); - - } + Format.sendMessage(sender, "You must be a player to use this command."); + return true; - } - - ItemMeta meta = item.getItemMeta(); - meta.setLore(list); - item.setItemMeta(meta); - - GuiItem guiItem = new GuiItem(item, event -> { - event.setCancelled(true); - if (section.isEnchantmentSection()) { - loadPurchasePane(section, itemInput, sender); - } else { - loadPurchasePane(section, itemInput, sender); - } - }); - - return guiItem; } - private double getEnchantmentPriceWithHeld(String enchantment, Player player) { - - ItemStack heldItem = player.getInventory().getItemInMainHand(); - double priceI = 0; - - if (heldItem != null) { - priceI = Main.getInstance().getCache().getItemPrice(heldItem.getType().toString(), false); - } - - return Main.getInstance().getCache().getOverallEnchantmentPrice(enchantment, priceI, false); - } - - private void loadPurchasePane(Section section, SectionItemData item, - CommandSender sender) { - - CommandUtil.closeInventory(sender); - ChestGui gui = new ChestGui(4, Config.getConfig().getMenuTitle()); - Material mat = Material.BARRIER; - - if (!Config.getConfig().getBackground().equalsIgnoreCase("none")) { - mat = Material.matchMaterial(Config.getConfig().getBackground()); - } - - gui = CommandUtil.getBackground(gui, 4, mat); - gui.addPane(getPurchasePane(item, sender, section)); - gui.addPane(generateMenuBackPane(sender)); - gui.show((HumanEntity) sender); - + @Override + protected void doShop(HumanEntity player, ChestGui gui, String shopName) { + gui.getPanes().clear(); + getBackground(gui); + gui.addPane(getGdpPane((Player) player, gui)); + gui.addPane(getBackToShop((Player) player, gui, ShopUtil.getShop(shopName).getSection())); + gui.addPane(getPurchasePane((Player) player, gui, shopName)); + gui.update(); } - private OutlinePane getPurchasePane(SectionItemData itemInput, - CommandSender sender, Section section) { - - Player player = (Player) sender; - DecimalFormat df = new DecimalFormat(Config.getConfig().getNumberFormat()); - OutlinePane pane = new OutlinePane(1, 1, 7, 2); - int k = -1; - - for (int amount : amounts) { - - ItemStack item; - k++; - - if (!section.isEnchantmentSection()) { - - item = getPurchasePaneItem(itemInput.getName(), - ChatColor.GREEN + "Buy for " + Config.getConfig().getCurrencySymbol() - + df.format(Main.getInstance().getCache().getItemPrice( - itemInput.getName(), false) * amount), amount); - - } else if (Config.getConfig().isEnableEnchantments()) { - - item = getPurchasePaneItem("ENCHANTED_BOOK", ChatColor.GREEN + "Buy for " - + Config.getConfig().getCurrencySymbol() + df.format( - getEnchantmentPriceWithHeld(itemInput.getName(), player) * amount), amount); - - ItemMeta meta = item.getItemMeta(); - meta.displayName(itemInput.getDisplayName()); - item.setItemMeta(meta); - - } else { - return pane; - } - - if (item.getMaxStackSize() < amount) { - - if (Config.getConfig().getBackground().equalsIgnoreCase("none")) { - - pane.setLength(k); - k--; - continue; + private OutlinePane getPurchasePane(Player player, ChestGui gui, String shopName) { + Shop shop = ShopUtil.getShop(shopName); + int length = shop.isEnchantment() ? ENCHANTMENT_AMOUNTS.length : AMOUNTS.length; + OutlinePane pane = new OutlinePane(1, 2, length, 2, Priority.HIGHEST); + List lore = Config.get().getPurchaseBuyLore(); + + Material material = shop.isEnchantment() ? Material.ENCHANTED_BOOK + : Material.matchMaterial(shopName); + + int[] amounts = shop.isEnchantment() ? ENCHANTMENT_AMOUNTS : AMOUNTS; + boolean buy = true; + + for (int i = 0; i < 2; i++) { + for (int amount : amounts) { + ItemStack item = new ItemStack(material); + + if (shop.isEnchantment()) { + Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(shopName)); + if (enchantment.getMaxLevel() < amount) { + GuiItem background = getBackgroundItem(); + if (background != null) { + pane.addItem(background); + } + continue; + } + final int finalAmount = amount; + item.editMeta(meta -> meta.displayName(enchantment.displayName(finalAmount))); } - ItemStack background = new ItemStack( - Material.matchMaterial(Config.getConfig().getBackground())); + if (!shop.isEnchantment()) { + int max = item.getMaxStackSize(); + if (amount > max) { + GuiItem background = getBackgroundItem(); + if (background != null) { + pane.addItem(background); + } + continue; + } + } - GuiItem guiItem = new GuiItem(background, event -> { + List loreList = getLore(player, shopName, lore, amount); + item.setAmount(amount); + item.lore(loreList); + final boolean isBuy = buy; + final int finalAmount = amount; + GuiItem guiItem = new GuiItem(item, event -> { event.setCancelled(true); + PurchaseUtil.purchaseItem(shopName, player, finalAmount, isBuy); + gui.getPanes().clear(); + getBackground(gui); + gui.addPane(getGdpPane((Player) player, gui)); + gui.addPane(getBackToShop((Player) player, gui, ShopUtil.getShop(shopName).getSection())); + gui.addPane(getPurchasePane(player, gui, shopName)); + gui.update(); }); - pane.addItem(guiItem); - continue; - } - - GuiItem guiItem = new GuiItem(item, event -> { - - event.setCancelled(true); - - if (!section.isEnchantmentSection()) { - - FunctionsUtil.buyItem(player, new ItemStack( - Material.matchMaterial(itemInput.getName()), amount)); - - } else { - - FunctionsUtil.buyEnchantment(player, itemInput.getName()); - } - - }); - - pane.addItem(guiItem); - } - - if (section.isEnchantmentSection()) { - return pane; - } - - for (int amount : amounts) { - - ItemStack item = getPurchasePaneItem(itemInput.getName(), ChatColor.RED + "Sell for " - + Config.getConfig().getCurrencySymbol() + df.format( - Main.getInstance().getCache().getItemPrice(itemInput.getName(), true) * amount), amount); - - if (item.getMaxStackSize() < amount) { - continue; - } - - GuiItem guiItem = new GuiItem(item, event -> { - - event.setCancelled(true); - - FunctionsUtil.sellItem(player, new ItemStack( - Material.matchMaterial(itemInput.getName()), amount)); - - }); - - pane.addItem(guiItem); + buy = false; + lore = Config.get().getPurchaseSellLore(); } - + return pane; } - private ItemStack getPurchasePaneItem(String itemInput, - String prefix, int amount) { - - ItemStack item = new ItemStack(Material.matchMaterial(itemInput), amount); - ItemMeta meta = item.getItemMeta(); - meta.lore(Arrays.asList(new Component[] { Component.text(ChatColor.WHITE + prefix)})); - item.setItemMeta(meta); - return item; - + @Override + protected List applyLore(Player player, String shopName, int amount) { + return getLore(player, shopName, Config.get().getShopLore(), amount); } - + } diff --git a/src/main/java/unprotesting/com/github/commands/TradeCommand.java b/src/main/java/unprotesting/com/github/commands/TradeCommand.java deleted file mode 100644 index fb5a3d9..0000000 --- a/src/main/java/unprotesting/com/github/commands/TradeCommand.java +++ /dev/null @@ -1,61 +0,0 @@ -package unprotesting.com.github.commands; - -import net.md_5.bungee.api.chat.ClickEvent; -import net.md_5.bungee.api.chat.ComponentBuilder; -import net.md_5.bungee.api.chat.HoverEvent; -import net.md_5.bungee.api.chat.TextComponent; - -import org.bukkit.ChatColor; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import unprotesting.com.github.Main; -import unprotesting.com.github.commands.util.CommandUtil; - - -public class TradeCommand implements CommandExecutor { - - @Override - public boolean onCommand(CommandSender sender, Command command, String trade, String[] args) { - - String[] arr = Main.getInstance().getServerIPs(); - - if (sender instanceof Player) { - - Player player = CommandUtil.closeInventory(sender); - - if (!(player.hasPermission("at.trade") || player.hasPermission("at.admin"))) { - - CommandUtil.noPermission(player); - return true; - - } - - player.spigot().sendMessage(createTextComponent(ChatColor.YELLOW - + "View Overall Item Prices", "Click to go to " + arr[0], arr[0])); - - return true; - - } - - Main.getInstance().getLogger().info("Go to: " + arr[0] + " for overall item prices."); - return true; - - } - - @Deprecated - private TextComponent createTextComponent(String base, String hover, String httpClick) { - - TextComponent message = new TextComponent(base); - - message.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, - new ComponentBuilder(hover).create())); - - message.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, httpClick)); - return message; - - } - -} diff --git a/src/main/java/unprotesting/com/github/commands/TransactionsCommand.java b/src/main/java/unprotesting/com/github/commands/TransactionsCommand.java deleted file mode 100644 index 70920e5..0000000 --- a/src/main/java/unprotesting/com/github/commands/TransactionsCommand.java +++ /dev/null @@ -1,201 +0,0 @@ -package unprotesting.com.github.commands; - -import com.github.stefvanschie.inventoryframework.gui.GuiItem; -import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; -import com.github.stefvanschie.inventoryframework.pane.OutlinePane; -import com.github.stefvanschie.inventoryframework.pane.PaginatedPane; - -import java.text.DecimalFormat; -import java.time.format.DateTimeFormatter; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.UUID; - -import net.kyori.adventure.text.Component; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.OfflinePlayer; -import org.bukkit.command.Command; -import org.bukkit.command.CommandExecutor; -import org.bukkit.command.CommandSender; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import unprotesting.com.github.Main; -import unprotesting.com.github.commands.util.CommandUtil; -import unprotesting.com.github.config.Config; -import unprotesting.com.github.data.ephemeral.data.TransactionData; -import unprotesting.com.github.data.ephemeral.other.Sale.SalePositionType; - -public class TransactionsCommand implements CommandExecutor { - - private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - - @Override - public boolean onCommand(CommandSender sender, Command command, - String transactions, String[] args) { - - if (!CommandUtil.checkIfSenderPlayer(sender)) { - return true; - } - - return interpretCommand(sender, args); - - } - - @Deprecated - private boolean interpretCommand(CommandSender sender, String[] args) { - - Player player = CommandUtil.closeInventory(sender); - - if (!(player.hasPermission("at.transactions") || player.hasPermission("at.admin"))) { - - CommandUtil.noPermission(player); - return true; - - } - - ChestGui gui = new ChestGui(6, "Transactions"); - PaginatedPane pages = new PaginatedPane(0, 0, 9, 6); - List loans = Main.getInstance().getCache().getTransactions(); - List panes = new ArrayList(); - String uuid = player.getUniqueId().toString(); - List items; - - if (args.length < 1) { - - if (!player.hasPermission("at.transactions.other") && !player.hasPermission("at.admin")) { - items = getGuiItemsFromTransactions(loans, uuid); - } else { - items = getGuiItemsFromTransactions(loans, null); - } - - } else if (args[0].equals("-p")) { - - if (args[1].equals(player.getName())) { - items = getGuiItemsFromTransactions(loans, uuid); - } else if (!args[1].equals(player.getName()) - && (!player.hasPermission("at.transactions.other") - && !player.hasPermission("at.admin"))) { - - CommandUtil.noPermission(player); - return true; - - } else { - - OfflinePlayer offPlayer = Bukkit.getOfflinePlayer(args[1]); - if (offPlayer == null) { - return false; - } - - uuid = offPlayer.getUniqueId().toString(); - - if (uuid == null) { - return false; - } - - items = getGuiItemsFromTransactions(loans, uuid); - - } - - } else { - return false; - } - - CommandUtil.loadGuiItemsIntoPane(items, gui, pages, - panes, Material.GRAY_STAINED_GLASS_PANE, sender); - - return true; - - } - - private List getGuiItemsFromTransactions(List data, - String uuid) { - - List output = new ArrayList(); - Collections.sort(data); - - for (TransactionData transaction : data) { - - if (uuid != null && !transaction.getPlayer().equals(uuid)) { - continue; - } - - if (transaction.getPosition().equals(SalePositionType.BUY) - || transaction.getPosition().equals(SalePositionType.SELL)) { - - ItemStack item = new ItemStack(Material.matchMaterial( - transaction.getItem()), transaction.getAmount()); - - ItemMeta meta = item.getItemMeta(); - - meta.setDisplayName(ChatColor.GOLD + Integer.toString(transaction.getAmount()) - + "x " + transaction.getItem()); - - List lore = new ArrayList(); - - if (transaction.getPosition().equals(SalePositionType.BUY)) { - lore.add(ChatColor.GREEN + "BUY"); - } else { - lore.add(ChatColor.RED + "SELL"); - } - - output.add(applyMetaToStack(meta, item, transaction, lore)); - continue; - - } - - Component displayName = Enchantment.getByKey( - NamespacedKey.minecraft(transaction.getItem().toLowerCase())).displayName(1); - - ItemStack item = new ItemStack(Material.ENCHANTED_BOOK); - ItemMeta meta = item.getItemMeta(); - meta.displayName(displayName); - List lore = new ArrayList(); - - if (transaction.getPosition().equals(SalePositionType.EBUY)) { - lore.add(ChatColor.GREEN + "BUY"); - } else { - lore.add(ChatColor.RED + "SELL"); - } - - output.add(applyMetaToStack(meta, item, transaction, lore)); - - } - - return output; - } - - private GuiItem applyMetaToStack(ItemMeta meta, ItemStack item, - TransactionData transaction, List lore) { - - DecimalFormat df = new DecimalFormat(Config.getConfig().getNumberFormat()); - OfflinePlayer player = Bukkit.getOfflinePlayer(UUID.fromString(transaction.getPlayer())); - String playerName = "Unknown"; - playerName = player.getName(); - lore.add(ChatColor.WHITE + "Player: " + playerName); - - lore.add(ChatColor.WHITE + "Price: " + Config.getConfig().getCurrencySymbol() - + df.format(transaction.getPrice())); - - lore.add(ChatColor.WHITE + "Total: " + Config.getConfig().getCurrencySymbol() - + df.format(transaction.getPrice() * transaction.getAmount())); - - lore.add(ChatColor.WHITE + "Date: " + transaction.getDate().format(formatter)); - meta.setLore(lore); - item.setItemMeta(meta); - - GuiItem guiItem = new GuiItem(item, event -> { - event.setCancelled(true); - }); - - return guiItem; - } - -} diff --git a/src/main/java/unprotesting/com/github/commands/objects/Section.java b/src/main/java/unprotesting/com/github/commands/objects/Section.java deleted file mode 100644 index 928b5d6..0000000 --- a/src/main/java/unprotesting/com/github/commands/objects/Section.java +++ /dev/null @@ -1,147 +0,0 @@ -package unprotesting.com.github.commands.objects; - -import java.util.ArrayList; -import java.util.List; - -import lombok.Data; -import net.kyori.adventure.text.Component; -import net.md_5.bungee.api.ChatColor; - -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.inventory.ItemStack; - -import unprotesting.com.github.Main; - -@Data -public class Section { - - private String name; - private String displayName; - private List items; - private Material image; - private Material background; - private boolean back; - private boolean enchantmentSection; - private int position; - - /** - * Creates a new Section object. - * The section object is used to store the data for a section. - * @param section The configuration section to load from. - * @param name The name of the section. - */ - public Section(ConfigurationSection section, String name) { - - this.displayName = ChatColor.translateAlternateColorCodes( - '&', section.getString("display-name", "&6" + name)); - - this.background = Material.matchMaterial( - section.getString("background", "GRAY_STAINED_GLASS_PANE")); - - this.name = name; - this.image = Material.matchMaterial(section.getString("block", "BARRIER")); - this.image = this.image == null ? Material.BARRIER : this.image; - this.back = section.getBoolean("back-menu-button-enabled", true); - this.enchantmentSection = name.equalsIgnoreCase("Enchantments"); - this.position = section.getInt("position", 0); - this.items = new ArrayList(); - - if (!this.isEnchantmentSection()) { - - ConfigurationSection shops = Main.getInstance().getDataFiles() - .getShops().getConfigurationSection("shops"); - - for (String key : shops.getKeys(false)) { - - ConfigurationSection inner = shops.getConfigurationSection(key); - - if (inner.getString("section").equals(this.name)) { - - this.items.add(new SectionItemData(key, - new ItemStack(Material.matchMaterial(key)).displayName(), - CollectFirstSetting.valueOf(inner.getString( - "collect-first-setting", "NONE").toLowerCase()))); - - } - - } - return; - } - - ConfigurationSection config = Main.getInstance().getDataFiles().getEnchantments() - .getConfigurationSection("enchantments"); - - for (String key : config.getKeys(false)) { - - CollectFirstSetting setting = CollectFirstSetting.none; - Component displayName = Component.text("Enchantment Error"); - - try { - - CollectFirstSetting.valueOf(config.getString( - "collect-first-setting", "none").toLowerCase()); - - } catch (Exception e) { - - Main.getInstance().getLogger().warning( - "Error in enchantments.yml: collect first setting for " + key); - - - } - - try { - - displayName = Enchantment.getByKey( - NamespacedKey.minecraft(key.toLowerCase())).displayName(1); - - } catch (Exception e) { - - Main.getInstance().getLogger().warning( - "Error in enchantments.yml: display name for " + key); - - e.printStackTrace(); - continue; - - } - - this.items.add(new SectionItemData(key, displayName, setting)); - - } - - } - - - public static enum CollectFirstSetting { - - none, - server_wide, - each_player - - } - - /** - * Get the position of the last section in the list. - * @param sections The list of sections. - * @return The position of the last section. - */ - public static int getHighest(List
sections) { - - int output = 0; - - for (Section section : sections) { - - if (section.getPosition() > output) { - output = section.getPosition(); - } - - } - - return output; - - } - - -} diff --git a/src/main/java/unprotesting/com/github/commands/objects/SectionItemData.java b/src/main/java/unprotesting/com/github/commands/objects/SectionItemData.java deleted file mode 100644 index 268255c..0000000 --- a/src/main/java/unprotesting/com/github/commands/objects/SectionItemData.java +++ /dev/null @@ -1,31 +0,0 @@ -package unprotesting.com.github.commands.objects; - -import lombok.Data; -import net.kyori.adventure.text.Component; - -import org.bukkit.Material; - -import unprotesting.com.github.commands.objects.Section.CollectFirstSetting; - -@Data -public class SectionItemData { - - private String name; - private Component displayName; - private Material image; - private CollectFirstSetting setting; - - /** - * Creates a new SectionItemData object. - * @param name The name of the item. - * @param displayName The display name of the item. - * @param setting The collect first setting of the item. - */ - public SectionItemData(String name, Component displayName, CollectFirstSetting setting) { - this.name = name; - this.image = Material.matchMaterial(name); - this.displayName = displayName; - this.setting = setting; - } - -} diff --git a/src/main/java/unprotesting/com/github/commands/util/CommandUtil.java b/src/main/java/unprotesting/com/github/commands/util/CommandUtil.java deleted file mode 100644 index 42175ad..0000000 --- a/src/main/java/unprotesting/com/github/commands/util/CommandUtil.java +++ /dev/null @@ -1,200 +0,0 @@ -package unprotesting.com.github.commands.util; - -import com.github.stefvanschie.inventoryframework.gui.GuiItem; -import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; -import com.github.stefvanschie.inventoryframework.pane.OutlinePane; -import com.github.stefvanschie.inventoryframework.pane.PaginatedPane; -import com.github.stefvanschie.inventoryframework.pane.Pane.Priority; -import com.github.stefvanschie.inventoryframework.pane.StaticPane; - -import java.util.List; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.Style; -import net.kyori.adventure.text.format.TextColor; -import net.kyori.adventure.text.format.TextDecoration; - -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.HumanEntity; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import unprotesting.com.github.Main; -import unprotesting.com.github.config.Messages; - -public class CommandUtil { - - /** - * Checks if the sender is a player. If so, return true. - * If not, send a message to the sender and return false. - * @param sender The CommandSender of the command. - * @return True if the sender is a player, false if not. - */ - public static boolean checkIfSenderPlayer(CommandSender sender) { - - if (!(sender instanceof Player)) { - sender.sendMessage("This command is for players only."); - return false; - } - - return true; - } - - public static void noPermission(Player p) { - p.sendMessage(Messages.getMessages().getNoPermission()); - } - - /** - * Closes the inventory of the sender if the sender is a player. - */ - public static Player closeInventory(CommandSender sender) { - - Player player = (Player) sender; - player.getOpenInventory().close(); - return player; - - } - - /** - * Gets the arrow pane for a shop GUI. - * @param page The page of the shop GUI. - * @param displayName The display name of the arrow pane. - * @param pane The pane of the arrow pane. - * @param back Whether the arrow pane should be present. - * I.e If back is false, the arrow pane will not be present. - * @param gui The shop GUI. - * @return The arrow pane. - */ - public static StaticPane getArrowPane(int page, String displayName, PaginatedPane pane, - boolean back, ChestGui gui) { - - StaticPane output = new StaticPane(0, 5, 1, 1); - - if (!back) { - output = new StaticPane(8, 5, 1, 1); - } - - ItemStack item = new ItemStack(Material.ARROW); - ItemMeta meta = item.getItemMeta(); - meta.displayName(Component.text(displayName, TextColor.color(255, 255, 255))); - item.setItemMeta(meta); - - GuiItem guiItem = new GuiItem(item, event -> { - - event.setCancelled(true); - pane.setPage(page); - gui.addPane(pane); - gui.update(); - - }); - - output.addItem(guiItem, 0, 0); - return output; - - } - - /** - * Load a list of GuiItems into a Pane. - * @param items The list of GuiItems. - * @param gui The GUI. - * @param pages The number of pages. - * @param panes The panes. - * @param background The background material. - * @param sender The CommandSender. - */ - public static void loadGuiItemsIntoPane(List items, ChestGui gui, PaginatedPane pages, - List panes, Material background, CommandSender sender) { - - int page = 0; - int k = 0; - OutlinePane pane = new OutlinePane(1, 1, 7, 4); - - if (items.size() > 28) { - pages.addPane(page, getArrowPane(page + 1, ChatColor.GRAY + "NEXT", pages, false, gui)); - } - - panes.add(pane); - - for (int i = 0; i < items.size(); i++) { - - pane = panes.get(panes.size() - 1); - - if (k > 27) { - - pane = new OutlinePane(1, 1, 7, 4); - page++; - pages.addPane(page, getArrowPane(page - 1, ChatColor.GRAY + "BACK", pages, true, gui)); - - if (i + 28 < items.size()) { - pages.addPane(page, getArrowPane(page + 1, ChatColor.GRAY + "NEXT", pages, false, gui)); - } - - panes.add(pane); - k = -1; - - } - - pane.addItem(items.get(i)); - k++; - - } - - int i = 0; - - for (OutlinePane outlinePane : panes) { - - pages.addPane(i, outlinePane); - i++; - - } - - gui.addPane(pages); - gui = getBackground(gui, 6, background); - gui.show((HumanEntity) (sender)); - - } - - /** - * Get the background pane for a GUI. - * @param gui The GUI. - * @param lines The number of lines. - * @param backgroundItem The background material. - */ - public static ChestGui getBackground(ChestGui gui, int lines, Material backgroundItem) { - - gui.setOnGlobalClick(event -> event.setCancelled(true)); - - if (backgroundItem == null || backgroundItem.equals(Material.BARRIER)) { - return gui; - } - - ItemStack item = new ItemStack(backgroundItem); - ItemMeta meta = item.getItemMeta(); - meta.displayName(Component.text("|", Style.style(TextDecoration.OBFUSCATED))); - item.setItemMeta(meta); - OutlinePane background = new OutlinePane(0, 0, 9, lines, Priority.LOWEST); - background.addItem(new GuiItem(item)); - background.setRepeat(true); - gui.addPane(background); - return gui; - - } - - /** - * Get a players autosell setting. - * @param player The player. - * @param item The item to get the setting for. - * @return True if the player is auto-selling the item, false if not. - */ - public static boolean getPlayerAutoSellSetting(Player player, String item) { - - String uuid = player.getUniqueId().toString(); - return Main.getInstance().getDataFiles().getPlayerData().getBoolean( - uuid + ".autosell." + item, false); - - } - -} diff --git a/src/main/java/unprotesting/com/github/commands/util/FunctionsUtil.java b/src/main/java/unprotesting/com/github/commands/util/FunctionsUtil.java deleted file mode 100644 index 45bd418..0000000 --- a/src/main/java/unprotesting/com/github/commands/util/FunctionsUtil.java +++ /dev/null @@ -1,399 +0,0 @@ -package unprotesting.com.github.commands.util; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import lombok.NonNull; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; - -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.jetbrains.annotations.NotNull; - -import unprotesting.com.github.Main; -import unprotesting.com.github.config.Config; -import unprotesting.com.github.config.Messages; -import unprotesting.com.github.data.ephemeral.data.AutosellData; -import unprotesting.com.github.data.ephemeral.other.Sale.SalePositionType; -import unprotesting.com.github.economy.EconomyFunctions; -import unprotesting.com.github.events.sync.UnlockUpdateEvent; -import unprotesting.com.github.util.UtilFunctions; - -public class FunctionsUtil { - - public static void buyItem(@NotNull Player player, @NotNull ItemStack item) { - - double balance = EconomyFunctions.getEconomy().getBalance(player); - double price = Main.getInstance().getCache().getItemPrice(item.getType().toString(), false); - int amount = item.getAmount(); - double total = price * amount; - String itemName = item.getType().toString(); - - TagResolver tagResolver = TagResolver.resolver( - Placeholder.component("item", item.displayName()), - Placeholder.unparsed("price", UtilFunctions.getDf().format(price)), - Placeholder.unparsed("amount", String.valueOf(amount)), - Placeholder.unparsed("balance", UtilFunctions.getDf().format(balance)), - Placeholder.unparsed("total", UtilFunctions.getDf().format(total))); - - if (price == 0) { - - Component message = Main.getInstance().getMm().deserialize( - Messages.getMessages().getNotInShop(), tagResolver); - - player.sendMessage(message); - - } - - if (!UnlockUpdateEvent.isUnlocked(player, itemName)) { - - Component message = Main.getInstance().getMm().deserialize( - Messages.getMessages().getNotUnlocked(), tagResolver); - - player.sendMessage(message); - return; - - } - - if (balance < total) { - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getNotEnoughMoney(), tagResolver)); - - amount = (int) Math.floor(balance / price); - - if (amount < 1) { - return; - } - - } - - if (Main.getInstance().getCache().getPurchasesLeft(itemName, player, true) < amount) { - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getRunOutOfBuys(), tagResolver)); - - return; - } - - HashMap map = player.getInventory() - .addItem(new ItemStack(Material.matchMaterial(itemName), amount)); - - if ((map.size()) > 0) { - - ItemStack itemStack = (ItemStack) (Arrays.asList(map.values().toArray())).get(0); - amount = amount - itemStack.getAmount(); - - } - - if (amount < 1) { - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getNotEnoughSpace(), tagResolver)); - - return; - } - - total = price * amount; - balance = EconomyFunctions.getEconomy().getBalance(player); - - tagResolver = TagResolver.resolver( - Placeholder.component("item", item.displayName()), - Placeholder.unparsed("price", UtilFunctions.getDf().format(price)), - Placeholder.unparsed("amount", String.valueOf(amount)), - Placeholder.unparsed("balance", UtilFunctions.getDf().format(balance)), - Placeholder.unparsed("total", UtilFunctions.getDf().format(total))); - - EconomyFunctions.getEconomy().withdrawPlayer(player, total); - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getShopPurchase(), tagResolver)); - - Main.getInstance().getCache().addSale( - player.getUniqueId(), itemName, price, amount, SalePositionType.BUY); - - } - - public static void sellItem(@NotNull Player player, @NotNull ItemStack item) { - - double balance = EconomyFunctions.getEconomy().getBalance(player); - double price = Main.getInstance().getCache().getItemPrice(item.getType().toString(), true); - int amount = item.getAmount(); - double total = price * amount; - String itemName = item.getType().toString(); - - TagResolver tagResolver = TagResolver.resolver( - Placeholder.component("item", item.displayName()), - Placeholder.parsed("price", UtilFunctions.getDf().format(price)), - Placeholder.parsed("amount", String.valueOf(amount)), - Placeholder.parsed("balance", UtilFunctions.getDf().format(balance)), - Placeholder.parsed("total", UtilFunctions.getDf().format(total))); - - if (price == 0) { - - Component message = Main.getInstance().getMm().deserialize( - Messages.getMessages().getNotInShop(), tagResolver); - - player.sendMessage(message); - } - - if (balance < total) { - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getNotEnoughMoney(), tagResolver)); - - amount = (int) Math.floor(balance / price); - - if (amount < 1) { - return; - } - - } - - if (Main.getInstance().getCache().getPurchasesLeft(itemName, player, false) < amount) { - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getRunOutOfSells(), tagResolver)); - - return; - } - - HashMap map = player.getInventory() - .removeItem(new ItemStack(Material.matchMaterial(itemName), amount)); - - if ((map.size()) > 0) { - - ItemStack itemStack = (ItemStack) (Arrays.asList(map.values().toArray())).get(0); - amount = amount - itemStack.getAmount(); - - } - - if (amount < 1) { - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getDoNotHaveItem(), tagResolver)); - - return; - } - - total = price * amount; - balance = EconomyFunctions.getEconomy().getBalance(player); - - tagResolver = TagResolver.resolver( - Placeholder.component("item", item.displayName()), - Placeholder.parsed("price", UtilFunctions.getDf().format(price)), - Placeholder.parsed("amount", String.valueOf(amount)), - Placeholder.parsed("balance", UtilFunctions.getDf().format(balance)), - Placeholder.parsed("total", UtilFunctions.getDf().format(total))); - - EconomyFunctions.getEconomy().depositPlayer(player, total); - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getShopSell(), tagResolver)); - - Main.getInstance().getCache().addSale( - player.getUniqueId(), itemName, price, amount, SalePositionType.SELL); - } - - public static void buyEnchantment(Player player, @NonNull String enchantment) { - - Enchantment enchant = Enchantment.getByKey(NamespacedKey.minecraft(enchantment)); - - if (!Config.getConfig().isEnableEnchantments()) { - Main.getInstance().getLogger().info("Enchantments are disabled."); - } - - ItemStack item = player.getInventory().getItemInMainHand(); - - if (item == null) { - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getHoldItemInHand())); - - return; - } - - int level = 0; - String enchantmentName = enchantment; - double balance = EconomyFunctions.getEconomy().getBalance(player); - - double itemPrice = Main.getInstance().getCache() - .getItemPrice(item.getType().toString(), false); - - double price = Main.getInstance().getCache() - .getOverallEnchantmentPrice(enchantment, itemPrice, false); - - TagResolver tagResolver = TagResolver.resolver( - Placeholder.parsed("enchantment", enchantmentName), - Placeholder.parsed("price", UtilFunctions.getDf().format(price)), - Placeholder.parsed("balance", UtilFunctions.getDf().format(balance)), - Placeholder.parsed("total", UtilFunctions.getDf().format(price)), - Placeholder.component("item", item.displayName())); - - if (price == 0) { - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getNotInShop(), tagResolver)); - - } - - if (item.containsEnchantment(enchant)) { - - level = item.getEnchantmentLevel(enchant); - - } - - if (balance < price) { - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getNotEnoughMoneyEnchantments(), tagResolver)); - - return; - } - - try { - item.addEnchantment(enchant, level + 1); - } catch (IllegalArgumentException e) { - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getEnchantmentError(), tagResolver)); - - return; - } - - EconomyFunctions.getEconomy().withdrawPlayer(player, price); - - Main.getInstance().getCache().addSale(player.getUniqueId(), - enchantment, price, 1, SalePositionType.EBUY); - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getEnchantmentPurchase(), tagResolver)); - - player.getInventory().setItemInMainHand(item); - } - - public static void sellCustomItem(@NonNull Player player, - @NonNull ItemStack item, boolean autosell) { - - Map enchantments = item.getEnchantments(); - double itemPrice = Main.getInstance().getCache().getItemPrice(item.getType().toString(), true); - int amount = item.getAmount(); - double total = itemPrice * amount; - - if (enchantments.size() > 0) { - - for (Enchantment enchantment : enchantments.keySet()) { - - double enchantmentPrice = Main.getInstance().getCache().getOverallEnchantmentPrice( - enchantment.getKey().asString(), itemPrice, true) - itemPrice; - - total += enchantmentPrice * item.getEnchantmentLevel(enchantment); - - } - - total = getNewPriceWithDurability(total, item); - total += itemPrice; - } - - - - if (total == 0) { - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getNotInShop())); - - } - - if (item.getAmount() < 1) { - - if (!autosell) { - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getCannotSellCustom())); - - player.getInventory().addItem(item); - - } - - return; - } - - double balance = EconomyFunctions.getEconomy().getBalance(player); - - TagResolver tagResolver = TagResolver.resolver( - Placeholder.parsed("price", UtilFunctions.getDf().format(total)), - Placeholder.parsed("balance", UtilFunctions.getDf().format(balance)), - Placeholder.parsed("total", UtilFunctions.getDf().format(total)), - Placeholder.component("item", item.displayName()), - Placeholder.parsed("amount", String.valueOf(amount))); - - if (Main.getInstance().getCache().getPurchasesLeft(item.getType().toString(), - player, false) < item.getAmount()) { - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getRunOutOfSells(), tagResolver)); - - player.getInventory().addItem(item); - return; - - } - - if (!autosell) { - - EconomyFunctions.getEconomy().depositPlayer(player, total); - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getSellCustomItem(), tagResolver)); - - } - - if (autosell) { - - AutosellData data = Main.getInstance().getAutosellData(); - data.add(player.getUniqueId().toString(), total); - Main.getInstance().setAutosellData(data); - - } - - Main.getInstance().getCache().addSale(player.getUniqueId(), item.getType().toString(), - itemPrice, amount, SalePositionType.SELL); - - for (Enchantment enchantment : item.getEnchantments().keySet()) { - - Main.getInstance().getCache().addSale(player.getUniqueId(), enchantment.getKey().toString(), - Main.getInstance().getCache().getEnchantmentPrice(enchantment.toString(), true), - item.getEnchantmentLevel(enchantment), SalePositionType.ESELL); - - } - - } - - @Deprecated - private static double getNewPriceWithDurability(double price, ItemStack item) { - - if (!item.getItemMeta().isUnbreakable()) { - return price; - } - - double durability = (double) item.getDurability(); - double maxDurability = (double) item.getType().getMaxDurability(); - - if (durability == 0) { - return price; - } - - double current = maxDurability - durability; - double result = (current / maxDurability); - double newPrice = price * result; - newPrice = newPrice - newPrice * 0.01 * Config.getConfig().getDurabilityLimiter(); - return newPrice; - - } -} diff --git a/src/main/java/unprotesting/com/github/commands/util/ShopFormat.java b/src/main/java/unprotesting/com/github/commands/util/ShopFormat.java deleted file mode 100644 index b4146b6..0000000 --- a/src/main/java/unprotesting/com/github/commands/util/ShopFormat.java +++ /dev/null @@ -1,143 +0,0 @@ -package unprotesting.com.github.commands.util; - -import com.github.stefvanschie.inventoryframework.gui.GuiItem; -import com.github.stefvanschie.inventoryframework.gui.type.ChestGui; -import com.github.stefvanschie.inventoryframework.pane.OutlinePane; -import com.github.stefvanschie.inventoryframework.pane.PaginatedPane; -import com.github.stefvanschie.inventoryframework.pane.StaticPane; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import net.kyori.adventure.text.Component; - -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.HumanEntity; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; - -import unprotesting.com.github.Main; -import unprotesting.com.github.commands.objects.Section; -import unprotesting.com.github.commands.objects.SectionItemData; -import unprotesting.com.github.config.Config; - -public abstract class ShopFormat { - - protected boolean interpretCommand(CommandSender sender, String[] args, String permission) { - - Player player = CommandUtil.closeInventory(sender); - int length = args.length; - - if (!(player.hasPermission(permission) || player.hasPermission("at.admin"))) { - CommandUtil.noPermission(player); - return true; - } - - if (length > 1) { - return false; - } - - if (length == 0) { - loadGui(sender); - return true; - } - - for (Section section : Main.getInstance().getCache().getSections()) { - - if (args[0].replace("-", "").replace(" ", "") - .equalsIgnoreCase(section.getName().replace("-", "").replace(" ", ""))) { - - loadShopPane(sender, section); - return true; - - } - - } - - return false; - - } - - protected void loadGui(CommandSender sender) { - - int highest = Section.getHighest(Main.getInstance().getCache().getSections()); - int lines = (highest / 9) + 2; - ChestGui gui = new ChestGui(lines, Config.getConfig().getMenuTitle()); - Material mat = Material.BARRIER; - - if (!Config.getConfig().getBackground().equalsIgnoreCase("none")) { - mat = Material.matchMaterial(Config.getConfig().getBackground()); - } - - gui = CommandUtil.getBackground(gui, lines, mat); - gui.addPane(loadSectionsPane(sender, lines)); - gui.show((HumanEntity) (sender)); - - } - - protected List getListFromSection(Section section, CommandSender sender) { - - List output = new ArrayList(); - - for (SectionItemData itemData : section.getItems()) { - GuiItem item = getGuiItem(section, itemData, sender); - if (item == null) { - continue; - } - output.add(item); - - } - return output; - } - - protected void loadShopPane(CommandSender sender, Section section) { - - CommandUtil.closeInventory(sender); - ChestGui gui = new ChestGui(6, Config.getConfig().getMenuTitle()); - PaginatedPane pages = new PaginatedPane(0, 0, 9, 6); - List items = getListFromSection(section, sender); - List panes = new ArrayList(); - CommandUtil.loadGuiItemsIntoPane(items, gui, pages, panes, section.getBackground(), sender); - - if (section.isBack()) { - gui.addPane(generateMenuBackPane(sender)); - } - - gui.update(); - } - - protected StaticPane generateMenuBackPane(CommandSender sender) { - - - ItemStack item = new ItemStack(Material.ARROW); - ItemMeta meta = item.getItemMeta(); - meta.displayName(Component.text((ChatColor.GRAY + "MENU"))); - - meta.lore(Arrays.asList(new Component[] { Component.text(ChatColor.WHITE - + "Click to go back to the main menu")})); - - item.setItemMeta(meta); - StaticPane output = new StaticPane(0, 0, 1, 1); - - GuiItem guiItem = new GuiItem(item, event -> { - - event.setCancelled(true); - event.getWhoClicked().getOpenInventory().close(); - loadGui(sender); - - }); - - output.addItem(guiItem, 0, 0); - return output; - } - - public abstract GuiItem getGuiItem(Section section, - SectionItemData itemInput, CommandSender sender); - - public abstract StaticPane loadSectionsPane(CommandSender sender, int lines); - -} diff --git a/src/main/java/unprotesting/com/github/config/Config.java b/src/main/java/unprotesting/com/github/config/Config.java index 9e3ea5e..088e306 100644 --- a/src/main/java/unprotesting/com/github/config/Config.java +++ b/src/main/java/unprotesting/com/github/config/Config.java @@ -1,112 +1,198 @@ package unprotesting.com.github.config; +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import java.util.logging.Level; + import lombok.Getter; -import lombok.Setter; -import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; -import unprotesting.com.github.Main; +import unprotesting.com.github.AutoTune; +import unprotesting.com.github.util.Format; @Getter -@Setter + public class Config { - @Getter + // The static instance of the config. private static Config config; + // The list of config filenames. + private static final String[] filenames = {"config.yml", "shops.yml", + "playerdata.yml", "messages.yml"}; + // The list of files. + private static File[] files; + // The list of configs. + private static YamlConfiguration[] configs; + + private final double timePeriod; + private final double volatility; + private final double sellPriceDifference; + private final Integer minimumPlayers; + private final double interest; + private final double tutorialUpdate; + private final Integer port; + private final String background; + private final String logLevel; + private final String locale; + + private final String notInShop; + private final String notEnoughMoney; + private final String notEnoughSpace; + private final String notEnoughItems; + private final String notUnlocked; + private final String runOutOfBuys; + private final String runOutOfSells; + private final String shopPurchase; + private final String shopSell; + private final String holdItemInHand; + private final String enchantmentError; + private final String autosellProfit; + private final String invalidShopSection; + + private final List shopLore; + private final List shopGdpLore; + private final List purchaseBuyLore; + private final List purchaseSellLore; + private final List autosellLore; + private final List tutorial; - private boolean webServerEnabled; - private boolean sellPriceDifferenceVariationEnabled; - private boolean tutorial; - private boolean disableMaxBuysSells; - private boolean ignoreAfk; - private boolean enableEnchantments; - private Integer port; - private Integer timePeriod; - private Integer sellPriceVariationTimePeriod; - private Integer sellPriceVariationUpdatePeriod; - private Integer autoSellUpdatePeriod; - private Integer autoSellProfitUpdatePeriod; - private Integer interestRateUpdateRate; - private Integer tutorialMessagePeriod; - private Integer updatePricesThreshold; - private String menuTitle; - private String apiKey; - private String email; - private String currencySymbol; - private String dataLocation; - private String background; - private String numberFormat; - private Double maxVolatility; - private Double minVolatility; - private Double sellPriceDifference; - private Double sellPriceDifferenceVariationStart; - private Double dataSelectionM; - private Double dataSelectionC; - private Double dataSelectionZ; - private Double interestRate; - private Double maxDebt; - private Double enchantmentLimiter; - private Double durabilityLimiter; - private String logLevel; + private final ConfigurationSection shops; + private final ConfigurationSection sections; + private ConfigurationSection autosell; /** - * Initializes the config. + * Initializes the config files. */ - public Config() { + public static void init() { + try { + initializeConfig(); + } catch (Exception e) { + AutoTune.getInstance().getLogger().info("Failed to initialize config."); + AutoTune.getInstance().getLogger().log(Level.SEVERE, "Config", e); + } + } - config = this; - loadConfig(); + private static void initializeConfig() { + files = new File[filenames.length]; + configs = new YamlConfiguration[filenames.length]; + config = new Config(); } /** - * Loads the config from the config.yml file. + * Gets the config. + * @return the config object */ - private void loadConfig() { - FileConfiguration configF = Main.getInstance().getDataFiles().getConfig(); - setApiKey(configF.getString("apiKey", "xyz")); - setEmail(configF.getString("email", "xyz@gmail.com")); - setWebServerEnabled(configF.getBoolean("web-server-enabled", true)); - setPort(configF.getInt("port", 8123)); - setTimePeriod(configF.getInt("time-period", 30)); - setMenuTitle(configF.getString("menu-title", "Shop")); - setBackground(configF.getString("background", "BLACK_STAINED_GLASS_PANE")); - setAutoSellUpdatePeriod(configF.getInt("auto-sell-update-period", 10)); - setAutoSellProfitUpdatePeriod(configF.getInt("auto-sell-profit-update-period", 600)); - setNumberFormat(configF.getString("number-format", "###,###,###,###,##0.00")); - setEnableEnchantments(configF.getBoolean("enable-enchantments", true)); - setSellPriceDifference(configF.getDouble("sell-price-difference", 15.0)); - setMaxVolatility(configF.getDouble("max-volatility", 0.5)); - setMinVolatility(configF.getDouble("min-volatility", 0.05)); - setDataSelectionM(configF.getDouble("data-selection-m", 0.05)); - setDataSelectionZ(configF.getDouble("data-selection-z", 1.75)); - setDataSelectionC(configF.getDouble("data-selection-c", 0.55)); - setUpdatePricesThreshold(configF.getInt("update-prices-threshold", 2)); - setCurrencySymbol(configF.getString("currency-symbol", "$")); - - setSellPriceDifferenceVariationEnabled(configF.getBoolean( - "sell-price-difference-variation-enabled", true)); - - setSellPriceDifferenceVariationStart(configF.getDouble( - "sell-price-difference-variation-start", 0.0)); - - setSellPriceVariationTimePeriod(configF.getInt( - "sell-price-variation-time-period", 43200)); - - setSellPriceVariationUpdatePeriod(configF.getInt( - "sell-price-variation-update-period", 30)); - - setInterestRate(configF.getDouble("interest-rate", 0.05)); - setInterestRateUpdateRate(configF.getInt("interest-rate-update-period", 1200)); - setDisableMaxBuysSells(configF.getBoolean("disable-max-buys-sells", false)); - setMaxDebt(configF.getDouble("max-debt-value", 1000.0)); - setEnchantmentLimiter(configF.getDouble("enchantment-limiter", 50.0)); - setDurabilityLimiter(configF.getDouble("durability-limiter", 15.0)); - setIgnoreAfk(configF.getBoolean("ignore-afk", true)); - setTutorial(configF.getBoolean("tutorial", true)); - setTutorialMessagePeriod(configF.getInt("tutorial-message-period", 360)); - setDataLocation(configF.getString("data-location", "plugins/Auto-Tune/")); - setLogLevel(configF.getString("log-level", "INFO")); + public static Config get() { + return config; + } + + private Config() { + for (int i = 0; i < filenames.length; i++) { + if (!new File(AutoTune.getInstance().getDataFolder(), filenames[i]).exists()) { + AutoTune.getInstance().saveResource(filenames[i], false); + } + } + + for (int i = 0; i < filenames.length; i++) { + File file = new File(AutoTune.getInstance().getDataFolder(), filenames[i]); + if (!file.exists()) { + AutoTune.getInstance().getLogger().info("Failed to load config file: " + filenames[i]); + continue; + } + files[i] = file; + configs[i] = YamlConfiguration.loadConfiguration(files[i]); + } + + this.logLevel = configs[0].getString("log-level", "INFO"); + Format.loadLogger(Level.parse(logLevel)); + + this.timePeriod = configs[0].getDouble("time-period", 30); + Format.getLog().finer("Time period: " + timePeriod); + this.volatility = configs[0].getDouble("volatility", 0.5); + Format.getLog().finer("Volatility: " + volatility); + this.sellPriceDifference = configs[0].getDouble("sell-price-difference", 20); + Format.getLog().finer("Sell price difference: " + sellPriceDifference); + this.minimumPlayers = configs[0].getInt("minimum-players", 2); + Format.getLog().finer("Minimum players: " + minimumPlayers); + this.interest = configs[0].getDouble("interest", 0.05); + Format.getLog().finer("Interest: " + interest); + this.tutorialUpdate = configs[0].getDouble("tutorial-update", 300); + Format.getLog().finer("Tutorial update: " + tutorialUpdate); + this.port = configs[0].getInt("port", 8989); + Format.getLog().finer("Port: " + port); + this.background = configs[0].getString("background", "BLACK_STAINED_GLASS_PANE"); + Format.getLog().finer("Background: " + background); + this.locale = configs[0].getString("locale", "en_US"); + Format.loadLocale(this.locale); + Format.getLog().finer("Locale: " + locale); + + this.notInShop = configs[3].getString("not-in-shop"); + Format.getLog().finest("Not in shop: " + notInShop); + this.notEnoughMoney = configs[3].getString("not-enough-money"); + Format.getLog().finest("Not enough money: " + notEnoughMoney); + this.notEnoughSpace = configs[3].getString("not-enough-space"); + Format.getLog().finest("Not enough space: " + notEnoughSpace); + this.notEnoughItems = configs[3].getString("not-enough-items"); + Format.getLog().finest("Not enough items: " + notEnoughItems); + this.notUnlocked = configs[3].getString("not-unlocked"); + Format.getLog().finest("Not unlocked: " + notUnlocked); + this.runOutOfBuys = configs[3].getString("run-out-of-buys"); + Format.getLog().finest("Run out of buys: " + runOutOfBuys); + this.runOutOfSells = configs[3].getString("run-out-of-sells"); + Format.getLog().finest("Run out of sells: " + runOutOfSells); + this.shopPurchase = configs[3].getString("shop-purchase"); + Format.getLog().finest("Shop purchase: " + shopPurchase); + this.shopSell = configs[3].getString("shop-sell"); + Format.getLog().finest("Shop sell: " + shopSell); + this.holdItemInHand = configs[3].getString("hold-item-in-hand"); + Format.getLog().finest("Hold item in hand: " + holdItemInHand); + this.enchantmentError = configs[3].getString("enchantment-error"); + Format.getLog().finest("Enchantment error: " + enchantmentError); + this.autosellProfit = configs[3].getString("autosell-profit"); + Format.getLog().finest("Autosell profit: " + autosellProfit); + this.invalidShopSection = configs[3].getString("invalid-shop-section"); + Format.getLog().finest("Invalid shop section: " + invalidShopSection); + + this.shopLore = configs[3].getStringList("shop-lore"); + Format.getLog().finest("Shop lore: " + Arrays.toString(shopLore.toArray())); + this.shopGdpLore = configs[3].getStringList("shop-gdp-lore"); + Format.getLog().finest("GDP shop lore: " + Arrays.toString(shopGdpLore.toArray())); + this.purchaseBuyLore = configs[3].getStringList("purchase-buy-lore"); + Format.getLog().finest("Purchase buy lore: " + Arrays.toString(purchaseBuyLore.toArray())); + this.purchaseSellLore = configs[3].getStringList("purchase-sell-lore"); + Format.getLog().finest("Purchase sell lore: " + Arrays.toString(purchaseSellLore.toArray())); + this.autosellLore = configs[3].getStringList("autosell-lore"); + Format.getLog().finest("Autosell lore: " + Arrays.toString(autosellLore.toArray())); + this.tutorial = configs[3].getStringList("tutorial"); + Format.getLog().finest("Tutorial: " + Arrays.toString(tutorial.toArray())); + + this.shops = configs[1].getConfigurationSection("shops"); + Format.getLog().finer("Loaded shops configuration."); + this.sections = configs[1].getConfigurationSection("sections"); + Format.getLog().finer("Loaded sections configuration."); + + this.autosell = configs[2].getConfigurationSection("autosell"); + Format.getLog().finer("Loaded autosell configuration."); } + /** + * Set a new configuration section for autosell data and save it. + * @param section The new section. + */ + public void setAutosell(ConfigurationSection section) { + this.autosell = section; + configs[2] = new YamlConfiguration(); + configs[2].set("autosell", section); + try { + configs[2].save(files[2]); + } catch (IOException e) { + Format.getLog().severe("Could not save playerdata configuration."); + } + } + } diff --git a/src/main/java/unprotesting/com/github/config/DataFiles.java b/src/main/java/unprotesting/com/github/config/DataFiles.java deleted file mode 100644 index 1eb9260..0000000 --- a/src/main/java/unprotesting/com/github/config/DataFiles.java +++ /dev/null @@ -1,102 +0,0 @@ -package unprotesting.com.github.config; - -import java.io.File; -import java.io.IOException; - -import lombok.Getter; - -import org.bukkit.configuration.InvalidConfigurationException; -import org.bukkit.configuration.file.YamlConfiguration; - -import unprotesting.com.github.Main; - -public class DataFiles { - - @Getter - private File[] files; - private YamlConfiguration[] configs; - - @Getter - private final String[] fileNames = { "config.yml", "shops.yml", "enchantments.yml", - "playerdata.yml", "messages.yml", "web/trade.html", "web/favicon.ico" }; - - /** - * Initializes the data files. - * @param dataFolder The plugin data folder. - */ - public DataFiles(File dataFolder) { - - this.files = new File[7]; - this.configs = new YamlConfiguration[5]; - - for (int i = 0; i < 5; i++) { - this.configs[i] = new YamlConfiguration(); - } - - for (int i = 0; i < files.length; i++) { - - File file = new File(dataFolder, fileNames[i]); - files[i] = file; - - } - - } - - /** - * Loads the configs for the data files. - */ - public void loadConfigs() { - - try { - - for (int i = 0; i < 5; i++) { - configs[i].load(files[i]); - } - - } catch (InvalidConfigurationException | IOException e) { - e.printStackTrace(); - } - - new Config(); - - } - - public YamlConfiguration getConfig() { - return configs[0]; - } - - public YamlConfiguration getShops() { - return configs[1]; - } - - public YamlConfiguration getEnchantments() { - return configs[2]; - } - - public YamlConfiguration getPlayerData() { - return configs[3]; - } - - public YamlConfiguration getMessages() { - return configs[4]; - } - - /** - * Set the playerdata YamlConfiguration. - * @param config The playerdata YamlConfiguration. - */ - public void setPlayerData(YamlConfiguration config) { - - configs[3] = config; - - try { - configs[3].save(files[3]); - } catch (IOException e) { - Main.getInstance().getLogger().severe("Could not save playerdata.yml!"); - } - - } - - - -} diff --git a/src/main/java/unprotesting/com/github/config/Messages.java b/src/main/java/unprotesting/com/github/config/Messages.java deleted file mode 100644 index 6d4ac9c..0000000 --- a/src/main/java/unprotesting/com/github/config/Messages.java +++ /dev/null @@ -1,69 +0,0 @@ -package unprotesting.com.github.config; - -import java.util.List; - -import lombok.Getter; - -import org.bukkit.configuration.file.FileConfiguration; - -import unprotesting.com.github.Main; - -@Getter -public class Messages { - - @Getter - private static Messages messages; - - private List onJoin; - private List tutorial; - private String notEnoughMoney; - private String runOutOfBuys; - private String notEnoughSpace; - private String notUnlocked; - private String notInShop; - private String shopPurchase; - private String doNotHaveItem; - private String runOutOfSells; - private String shopSell; - private String holdItemInHand; - private String notEnoughMoneyEnchantments; - private String enchantmentError; - private String enchantmentPurchase; - private String cannotSellCustom; - private String sellCustomItem; - private String autoSellProfitUpdate; - private String loanSuccess; - private String noPermission; - - public Messages() { - messages = this; - loadMessages(); - } - - private void loadMessages() { - - FileConfiguration config = Main.getInstance().getDataFiles().getMessages(); - onJoin = config.getStringList("on-join"); - tutorial = config.getStringList("tutorial"); - notEnoughMoney = config.getString("not-enough-money"); - runOutOfBuys = config.getString("run-out-of-buys"); - notEnoughSpace = config.getString("not-enough-space"); - notUnlocked = config.getString("not-unlocked"); - notInShop = config.getString("not-in-shop"); - shopPurchase = config.getString("shop-purchase"); - doNotHaveItem = config.getString("do-not-have-item"); - runOutOfSells = config.getString("run-out-of-sells"); - shopSell = config.getString("shop-sell"); - holdItemInHand = config.getString("hold-item-in-hand"); - notEnoughMoneyEnchantments = config.getString("not-enough-money-enchantments"); - enchantmentError = config.getString("enchantment-error"); - enchantmentPurchase = config.getString("enchantment-purchase"); - cannotSellCustom = config.getString("cannot-sell-custom"); - sellCustomItem = config.getString("sell-custom-item"); - autoSellProfitUpdate = config.getString("autosell-profit-update"); - loanSuccess = config.getString("loan-success"); - noPermission = config.getString("no-permission"); - - } - -} diff --git a/src/main/java/unprotesting/com/github/data/CollectFirst.java b/src/main/java/unprotesting/com/github/data/CollectFirst.java new file mode 100644 index 0000000..9c5e156 --- /dev/null +++ b/src/main/java/unprotesting/com/github/data/CollectFirst.java @@ -0,0 +1,72 @@ +package unprotesting.com.github.data; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.Setter; + +@AllArgsConstructor +public class CollectFirst implements Serializable { + + private static final long serialVersionUID = 4793403925265988249L; + + // The CollectFirst setting + @Getter + protected final CollectFirstSetting setting; + // The list of players who have collected the item + protected List players; + // Whether the item has been found anywhere on the server + @Getter @Setter + protected boolean foundInServer; + + /** + * Constructor for the collect first class. + * @param setting The collect first setting for this shop. + */ + protected CollectFirst(String cfSetting) { + + cfSetting = cfSetting.toLowerCase(); + if (cfSetting.equalsIgnoreCase("player")) { + this.setting = CollectFirstSetting.PLAYER; + } else if (cfSetting.equalsIgnoreCase("server")) { + this.setting = CollectFirstSetting.SERVER; + } else { + this.setting = CollectFirstSetting.NONE; + } + + this.players = new ArrayList<>(); + this.foundInServer = false; + } + + public static enum CollectFirstSetting { + PLAYER, + SERVER, + NONE + } + + /** + * Adds a player to the list of players who have collected the item. + */ + public void addPlayer(UUID player) { + if (!players.contains(player)) { + players.add(player); + } + + } + + /** + * Whether or not the player is in the map. + * I.e they have found this item. + * @param player The player uuid. + * @return Whether or not the player is in the map. + */ + public boolean playerFound(UUID player) { + return players.contains(player); + } + + +} diff --git a/src/main/java/unprotesting/com/github/data/CollectFirstSerializer.java b/src/main/java/unprotesting/com/github/data/CollectFirstSerializer.java new file mode 100644 index 0000000..a619440 --- /dev/null +++ b/src/main/java/unprotesting/com/github/data/CollectFirstSerializer.java @@ -0,0 +1,41 @@ +package unprotesting.com.github.data; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.mapdb.DataInput2; +import org.mapdb.DataOutput2; +import org.mapdb.Serializer; + +import unprotesting.com.github.data.CollectFirst.CollectFirstSetting; + +public class CollectFirstSerializer implements Serializer { + + @Override + public void serialize(DataOutput2 out, CollectFirst value) throws IOException { + out.writeUTF(value.setting.name()); + out.writeInt(value.players.size()); + + for (UUID player : value.players) { + UUID.serialize(out, player); + } + + out.writeBoolean(value.foundInServer); + } + + @Override + public CollectFirst deserialize(DataInput2 input, int available) throws IOException { + CollectFirstSetting setting = CollectFirstSetting.valueOf(input.readUTF()); + int size = input.readInt(); + List players = new ArrayList<>(); + + for (int i = 0; i < size; i++) { + players.add(UUID.deserialize(input, available)); + } + + boolean foundInServer = input.readBoolean(); + return new CollectFirst(setting, players, foundInServer); + } +} diff --git a/src/main/java/unprotesting/com/github/data/Database.java b/src/main/java/unprotesting/com/github/data/Database.java new file mode 100644 index 0000000..b5951f0 --- /dev/null +++ b/src/main/java/unprotesting/com/github/data/Database.java @@ -0,0 +1,287 @@ +package unprotesting.com.github.data; + +import java.util.HashMap; +import java.util.UUID; + +import lombok.Getter; + +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.OfflinePlayer; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.enchantments.Enchantment; +import org.eclipse.collections.api.tuple.Pair; +import org.eclipse.collections.impl.tuple.Tuples; +import org.mapdb.DB; +import org.mapdb.DBMaker; +import org.mapdb.HTreeMap; +import org.mapdb.Serializer; +import org.mapdb.serializer.SerializerCompressionWrapper; + +import unprotesting.com.github.AutoTune; +import unprotesting.com.github.config.Config; +import unprotesting.com.github.util.EconomyUtil; +import unprotesting.com.github.util.Format; + +public class Database { + + private static Database instance; + + private static final String[] ECONOMY_DATA_KEYS = { + "GDP", "BALANCE", "DEBT", "LOSS", "INFLATION", "POPULATION"}; + + // The MapDB database. + private DB db; + // The map of item name to shop. + protected HTreeMap shops; + // The map of times to Transactions + @Getter + protected HTreeMap transactions; + // The map of times to Loans + @Getter + protected HTreeMap loans; + // The map of economy data name to economy data history. + protected HTreeMap economyData; + // The map of section name to section. + protected HashMap sections; + // The map of a pair of shop names to a relation. + protected HashMap, Relation> relations; + + /** + * Constructor for the Database class. + */ + public Database() { + instance = this; + createDB(AutoTune.getInstance().getDataFolder() + "/data.db"); + this.sections = new HashMap(); + createMaps(); + loadShopDefaults(); + updateChanges(); + loadSectionData(); + loadEconomyData(); + } + + /** + * Get the static instance of the database. + * @return The static instance of the database. + */ + public static Database get() { + return instance; + } + + /** + * Close the database. + */ + public void close() { + if (db != null) { + db.close(); + } + } + + /** + * Update the percentage changes for each shop. + */ + public void updateChanges() { + for (String name : shops.keySet()) { + Shop shop = getShop(name); + shop.updateChange(); + putShop(name, shop); + Format.getLog().finest(name + "'s change is now " + + Format.percent(getShop(name).getChange())); + } + } + + /** + * Update the relations in the shop. + */ + public void updateRelations() { + for (String name : shops.keySet()) { + for (String name2 : shops.keySet()) { + + if (name.equals(name2)) { + continue; + } + + Pair pair = Tuples.pair(name, name2); + Relation relation = new Relation(getShop(name), getShop(name2)); + relations.put(pair, relation); + } + } + } + + /** + * Update a loan value. + * @param key The key of the loan. + * @param loan The loan to update. + */ + public void updateLoan(Long key, Loan loan) { + if (loans.containsKey(key)) { + loans.put(key, loan); + } else { + Format.getLog().severe("Tried to update a loan that doesn't exist!"); + } + } + + protected Shop getShop(String s) { + String item = s.toLowerCase(); + + if (shops.get(item) == null) { + Format.getLog().severe("Could not find shop for " + item); + return null; + } + + return shops.get(item); + } + + protected void putShop(String key, Shop shop) { + String name = key.toLowerCase(); + if (shops.containsKey(name)) { + shops.put(name, shop); + } + } + + protected String[] getShopNames() { + return shops.keySet().toArray(new String[0]); + } + + protected int getPurchasesLeft(String item, UUID player, boolean isBuy) { + Shop shop = getShop(item); + int max = isBuy ? shop.getMaxBuys() : shop.getMaxSells(); + + if (isBuy) { + max -= shop.getRecentBuys().getOrDefault(player, 0); + } else { + max -= shop.getRecentSells().getOrDefault(player, 0); + } + + return max; + } + + private void createDB(String location) { + db = DBMaker.fileDB(location) + .checksumHeaderBypass() + .fileMmapEnableIfSupported() + .fileMmapPreclearDisable() + .cleanerHackEnable() + .allocateStartSize(10 * 1024 * 1024) + .allocateIncrement(5 * 1024 * 1024) + .closeOnJvmShutdown().make(); + db.getStore().fileLoad(); + Format.getLog().config("Database initialized at " + location); + } + + private void loadSectionData() { + for (String key : Config.get().getSections().getKeys(false)) { + key = key.toLowerCase(); + ConfigurationSection section = Config.get().getSections().getConfigurationSection(key); + sections.put(key, new Section(key, section)); + Format.getLog().fine("Section " + key + " loaded."); + } + } + + private void loadShopDefaults() { + + ConfigurationSection config = Config.get().getShops(); + + for (String sectionName : config.getKeys(false)) { + + ConfigurationSection sectionConfig = config.getConfigurationSection(sectionName); + + for (String key : config.getConfigurationSection(sectionName).getKeys(false)) { + + key = key.toLowerCase(); + Material material = Material.matchMaterial(key); + Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(key)); + + if (material == null && enchantment == null) { + Format.getLog().warning("Invalid shop. " + + key + " is not a valid material or enchantment."); + continue; + } + + boolean isEnchantment = enchantment != null; + ConfigurationSection section = sectionConfig.getConfigurationSection(key); + + if (shops.containsKey(key)) { + getShop(key).loadConfiguration(section, sectionName); + Format.getLog().finer("Shop " + key + " loaded."); + continue; + } + + shops.put(key, new Shop(section, sectionName, isEnchantment)); + + Format.getLog().fine("New shop " + key + " in section " + shops.get(key).getSection()); + + } + + } + } + + private void loadEconomyData() { + + if (economyData.isEmpty()) { + for (String key : ECONOMY_DATA_KEYS) { + economyData.put(key, new double[1]); + } + } + + EconomyDataUtil.updateEconomyData("INFLATION", calculateInflation()); + EconomyDataUtil.updateEconomyData("POPULATION", calculatePopulation()); + EconomyDataUtil.updateEconomyData("BALANCE", calculateBalance()); + } + + private double calculateInflation() { + double inflation = 0; + for (Shop shop : shops.values()) { + inflation += shop.getChange(); + } + inflation /= shops.size(); + return inflation; + } + + private double calculatePopulation() { + double population = 0; + for (OfflinePlayer player : AutoTune.getInstance().getServer().getOfflinePlayers()) { + if (player == null) { + continue; + } + population++; + } + return population; + } + + private double calculateBalance() { + double balance = 0; + for (OfflinePlayer player : AutoTune.getInstance().getServer().getOfflinePlayers()) { + balance += EconomyUtil.getEconomy().getBalance(player); + } + return balance; + } + + private void createMaps() { + this.shops = db.hashMap("shops") + .keySerializer(new SerializerCompressionWrapper(Serializer.STRING)) + .valueSerializer(new ShopSerializer()) + .createOrOpen(); + Format.getLog().fine("Loaded shops map."); + this.transactions = db.hashMap("transactions") + .keySerializer(new SerializerCompressionWrapper(Serializer.LONG)) + .valueSerializer(new TransactionSerializer()) + .createOrOpen(); + Format.getLog().fine("Loaded transactions map."); + this.loans = db.hashMap("loans") + .keySerializer(new SerializerCompressionWrapper(Serializer.LONG)) + .valueSerializer(new LoanSerializer()) + .createOrOpen(); + Format.getLog().fine("Loaded loans map."); + this.economyData = db.hashMap("economyData") + .keySerializer(new SerializerCompressionWrapper(Serializer.STRING)) + .valueSerializer(Serializer.DOUBLE_ARRAY) + .createOrOpen(); + Format.getLog().fine("Loaded economy data map."); + this.relations = new HashMap<>(); + } + + + +} diff --git a/src/main/java/unprotesting/com/github/data/EconomyDataUtil.java b/src/main/java/unprotesting/com/github/data/EconomyDataUtil.java new file mode 100644 index 0000000..595dd7d --- /dev/null +++ b/src/main/java/unprotesting/com/github/data/EconomyDataUtil.java @@ -0,0 +1,62 @@ +package unprotesting.com.github.data; + +public class EconomyDataUtil { + + /** + * Update the economy data of ta given economy data setting. + * @param key The key of the economy data setting. + * @param value The new value of the economy data setting. + */ + public static void updateEconomyData(String key, double value) { + double[] data = Database.get().economyData.get(key); + data[data.length - 1] = value; + Database.get().economyData.put(key, data); + } + + /** + * Increase the economy data of a given economy data setting. + * @param key The key of the economy data setting. + * @param value The value to increase the economy data setting by. + */ + public static void increaseEconomyData(String key, double value) { + double[] data = Database.get().economyData.get(key); + data[data.length - 1] += value; + Database.get().economyData.put(key, data); + } + + public static double getGdp() { + double[] data = Database.get().economyData.get("GDP"); + return data[data.length - 1]; + } + + public static double getBalance() { + double[] data = Database.get().economyData.get("BALANCE"); + return data[data.length - 1]; + } + + public static int getPopulation() { + double[] data = Database.get().economyData.get("POPULATION"); + return (int) data[data.length - 1]; + } + + public static double getLoss() { + double[] data = Database.get().economyData.get("LOSS"); + return data[data.length - 1]; + } + + public static double getDebt() { + double[] data = Database.get().economyData.get("DEBT"); + return data[data.length - 1]; + } + + public static double getInflation() { + double[] data = Database.get().economyData.get("INFLATION"); + return data[data.length - 1]; + } + + + + + + +} diff --git a/src/main/java/unprotesting/com/github/data/Loan.java b/src/main/java/unprotesting/com/github/data/Loan.java new file mode 100644 index 0000000..0b7463e --- /dev/null +++ b/src/main/java/unprotesting/com/github/data/Loan.java @@ -0,0 +1,60 @@ +package unprotesting.com.github.data; + +import java.io.Serializable; +import java.util.UUID; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; + +import unprotesting.com.github.config.Config; +import unprotesting.com.github.util.EconomyUtil; + +@AllArgsConstructor +@Data +@Builder +public class Loan implements Serializable { + + private static final long serialVersionUID = -5882241259956156012L; + + protected double value; + protected double base; + protected UUID player; + protected boolean paid; + + /** + * Pay back the given loan. + * @return Whether or not the loan was paid back. + */ + public boolean payBack() { + OfflinePlayer offPlayer = Bukkit.getOfflinePlayer(player); + double balance = EconomyUtil.getEconomy().getBalance(offPlayer); + + if (balance < value) { + return false; + } + + EconomyUtil.getEconomy().withdrawPlayer(offPlayer, value); + paid = true; + EconomyDataUtil.increaseEconomyData("LOSS", value - base); + return true; + } + + /** + * Update the value of the loan. + */ + public void update() { + + value += value * 0.01 * Config.get().getInterest(); + OfflinePlayer offPlayer = Bukkit.getOfflinePlayer(player); + double balance = EconomyUtil.getEconomy().getBalance(offPlayer); + + if (balance <= value + value * 0.01 * Config.get().getInterest()) { + payBack(); + } + } + +} diff --git a/src/main/java/unprotesting/com/github/data/LoanSerializer.java b/src/main/java/unprotesting/com/github/data/LoanSerializer.java new file mode 100644 index 0000000..55c26e0 --- /dev/null +++ b/src/main/java/unprotesting/com/github/data/LoanSerializer.java @@ -0,0 +1,28 @@ +package unprotesting.com.github.data; + +import java.io.IOException; + +import org.mapdb.DataInput2; +import org.mapdb.DataOutput2; +import org.mapdb.Serializer; + +public class LoanSerializer implements Serializer { + + @Override + public void serialize(DataOutput2 out, Loan value) throws IOException { + out.writeDouble(value.getValue()); + out.writeDouble(value.getBase()); + UUID.serialize(out, value.player); + out.writeBoolean(value.isPaid()); + } + + @Override + public Loan deserialize(DataInput2 in, int available) throws IOException { + Loan.LoanBuilder builder = new Loan.LoanBuilder(); + builder.value(in.readDouble()); + builder.base(in.readDouble()); + builder.player(UUID.deserialize(in, available)); + builder.paid(in.readBoolean()); + return builder.build(); + } +} diff --git a/src/main/java/unprotesting/com/github/data/PurchaseUtil.java b/src/main/java/unprotesting/com/github/data/PurchaseUtil.java new file mode 100644 index 0000000..4265434 --- /dev/null +++ b/src/main/java/unprotesting/com/github/data/PurchaseUtil.java @@ -0,0 +1,275 @@ +package unprotesting.com.github.data; + +import java.util.HashMap; +import java.util.UUID; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; + +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.PlayerInventory; + +import unprotesting.com.github.config.Config; +import unprotesting.com.github.data.Transaction.TransactionType; +import unprotesting.com.github.util.EconomyUtil; +import unprotesting.com.github.util.Format; + +public class PurchaseUtil { + + /** + * Purchase/sell an item from a shop. + * @param name The name of the shop. + * @param player The player uuid. + * @param amount The item to purchase. + */ + public static void purchaseItem(String name, Player player, int amount, boolean isBuy) { + Shop shop = getAssociatedShop(player, name); + + if (shop == null) { + return; + } + + Component display = Shop.getDisplayName(name, shop.isEnchantment()); + double price = isBuy ? shop.getPrice() : shop.getSellPrice(); + double total = price * amount; + double balance = EconomyUtil.getEconomy().getBalance(player); + TagResolver r = getTagResolver(display, price, amount, balance, shop.getSetting()); + UUID uuid = player.getUniqueId(); + + if (isBuy && !shop.isUnlocked(uuid)) { + Format.sendMessage(player, Config.get().getNotUnlocked(), r); + return; + } + + if (isBuy && balance < total) { + Format.sendMessage(player, Config.get().getNotEnoughMoney(), r); + return; + } + + if (Database.get().getPurchasesLeft(name, uuid, isBuy) - amount < 0) { + if (isBuy) { + Format.sendMessage(player, Config.get().getRunOutOfBuys(), r); + } else { + Format.sendMessage(player, Config.get().getRunOutOfSells(), r); + } + return; + } + + boolean success = shop.isEnchantment() ? enchant(player, name, amount, isBuy, r) + : item(player, name, amount, isBuy, r); + + if (!success) { + return; + } + + TransactionType position = isBuy ? TransactionType.BUY : TransactionType.SELL; + Transaction transaction = new Transaction(price, amount, uuid, name, position); + Database.get().transactions.put(System.currentTimeMillis(), transaction); + EconomyDataUtil.increaseEconomyData("GDP", total / 2); + + if (isBuy) { + shop.addBuys(uuid, amount); + } else { + shop.addSells(uuid, amount); + } + + if (isBuy) { + EconomyUtil.getEconomy().withdrawPlayer(player, total); + } else { + EconomyUtil.getEconomy().depositPlayer(player, total); + } + + String message = isBuy ? Config.get().getShopPurchase() : Config.get().getShopSell(); + Format.sendMessage(player, message, r); + double loss = shop.getPrice() * amount - total; + EconomyDataUtil.increaseEconomyData("LOSS", loss); + ShopUtil.putShop(name, shop); + } + + /** + * Sell an item stack to all relevant shops. + * @param item The item stack to sell. + * @param player The player object. + */ + public static void sellItemStack(ItemStack item, Player player) { + int amount = item.getAmount(); + boolean success = true; + double total = 0; + double balance = EconomyUtil.getEconomy().getBalance(player); + UUID uuid = player.getUniqueId(); + TagResolver r = getTagResolver(item.displayName(), total / amount, amount, balance, null); + + for (Enchantment enchantment : item.getEnchantments().keySet()) { + String name = enchantment.getKey().getKey(); + Shop shop = getAssociatedShop(player, name); + + if (shop == null) { + Format.sendMessage(player, Config.get().getNotInShop(), r); + success = false; + break; + } + + double price = shop.getSellPrice() * item.getEnchantmentLevel(enchantment); + total += price * amount; + r = getTagResolver(item.displayName(), price, amount, balance, null); + + if (ShopUtil.getSellsLeft(player, name) - amount < 0) { + Format.sendMessage(player, Config.get().getRunOutOfSells(), r); + success = false; + break; + } + + } + + String itemName = item.getType().toString().toLowerCase(); + Shop itemShop = ShopUtil.getShop(itemName); + + if (itemShop == null) { + Format.sendMessage(player, Config.get().getNotInShop(), r); + player.getInventory().addItem(item); + return; + } + + double price = itemShop.getSellPrice(); + total += price * amount; + r = getTagResolver(item.displayName(), price, amount, balance, null); + + if (ShopUtil.getSellsLeft(player, itemName) - amount < 0) { + Format.sendMessage(player, Config.get().getRunOutOfSells(), r); + success = false; + } + + r = getTagResolver(item.displayName(), total / amount, amount, balance, null); + + if (!success) { + player.getInventory().addItem(item); + return; + } + + for (Enchantment enchantment : item.getEnchantments().keySet()) { + + String name = enchantment.getKey().getKey(); + Shop shop = getAssociatedShop(player, name); + Transaction transaction = new Transaction(price, amount, uuid, name, TransactionType.SELL); + Database.get().transactions.put(System.currentTimeMillis(), transaction); + EconomyDataUtil.increaseEconomyData("GDP", total / 2); + double loss = shop.getPrice() - shop.getSellPrice(); + EconomyDataUtil.increaseEconomyData("LOSS", loss * amount); + shop.addSells(uuid, amount); + ShopUtil.putShop(name, shop); + } + + Transaction transaction = new Transaction(price, amount, uuid, itemName, TransactionType.SELL); + Database.get().transactions.put(System.currentTimeMillis(), transaction); + EconomyDataUtil.increaseEconomyData("GDP", total / 2); + double loss = itemShop.getPrice() - itemShop.getSellPrice(); + EconomyDataUtil.increaseEconomyData("LOSS", loss * amount); + itemShop.addSells(uuid, amount); + ShopUtil.putShop(itemName, itemShop); + EconomyUtil.getEconomy().withdrawPlayer(player, total); + Format.sendMessage(player, Config.get().getShopSell(), r); + + } + + private static TagResolver getTagResolver(Component display, double price, + int amount, double balance, CollectFirst cf) { + TagResolver.Builder builder = TagResolver.builder(); + builder.resolver(TagResolver.resolver( + Placeholder.component("item", display), + Placeholder.parsed("total", Format.currency(price * amount)), + Placeholder.parsed("price", Format.currency(price)), + Placeholder.parsed("amount", Integer.toString(amount)), + Placeholder.parsed("balance", Format.currency(balance)))); + if (cf != null) { + builder.resolver(Placeholder.parsed("collect-first-setting", + cf.getSetting().toString().toLowerCase())); + } + return builder.build(); + } + + private static Shop getAssociatedShop(Player player, String name) { + name = name.toLowerCase(); + Shop shop = ShopUtil.getShop(name); + + if (shop == null) { + Format.sendMessage(player, Config.get().getNotInShop()); + return null; + } + return shop; + } + + private static boolean item(Player player, String name, int amount, + boolean isBuy, TagResolver r) { + PlayerInventory inv = player.getInventory(); + ItemStack item = new ItemStack(Material.matchMaterial(name), amount); + HashMap map = isBuy ? inv.addItem(item) : inv.removeItem(item); + + if (map.isEmpty()) { + return true; + } + + if (!isBuy) { + ItemStack returned = map.get(0); + returned.setAmount(amount - returned.getAmount()); + inv.addItem(returned); + Format.sendMessage(player, Config.get().getNotEnoughItems(), r); + return false; + } + + Format.sendMessage(player, Config.get().getNotEnoughSpace(), r); + player.getWorld().dropItemNaturally(player.getLocation(), map.get(0)); + return true; + } + + private static boolean enchant(Player player, String name, int amount, + boolean isBuy, TagResolver r) { + Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(name)); + ItemStack item = player.getInventory().getItemInMainHand(); + + if (item == null || item.getType() == Material.AIR) { + Format.sendMessage(player, Config.get().getHoldItemInHand(), r); + return false; + } + + if (isBuy) { + int level = item.getEnchantmentLevel(enchantment); + + try { + item.addEnchantment(enchantment, level + amount); + } catch (IllegalArgumentException e) { + Format.sendMessage(player, Config.get().getEnchantmentError(), r); + return false; + } + + return true; + } else { + + if (!item.containsEnchantment(enchantment)) { + Format.sendMessage(player, Config.get().getHoldItemInHand(), r); + return false; + } + + if (item.getEnchantmentLevel(enchantment) < amount) { + Format.sendMessage(player, Config.get().getNotEnoughItems(), r); + return false; + } + + if (item.getEnchantmentLevel(enchantment) == amount) { + item.removeEnchantment(enchantment); + } else { + item.addEnchantment(enchantment, item.getEnchantmentLevel(enchantment) - amount); + } + + return true; + + } + } + + + +} diff --git a/src/main/java/unprotesting/com/github/data/Relation.java b/src/main/java/unprotesting/com/github/data/Relation.java new file mode 100644 index 0000000..8364627 --- /dev/null +++ b/src/main/java/unprotesting/com/github/data/Relation.java @@ -0,0 +1,28 @@ +package unprotesting.com.github.data; + +import lombok.Data; + +import org.eclipse.collections.api.tuple.Pair; +import org.eclipse.collections.impl.tuple.Tuples; + +@Data +public class Relation { + + private double relation; + private Pair buys; + private Pair sells; + + /** + * Constructor for a relation class. + * @param shop The shop to get the relation from. + * @param shop2 The shop to get the relation to. + */ + protected Relation(Shop shop, Shop shop2) { + this.buys = Tuples.pair(shop.getTotalBuys(), shop2.getTotalBuys()); + this.sells = Tuples.pair(shop.getTotalSells(), shop2.getTotalSells()); + this.relation = shop.getPrice() / shop2.getPrice(); + } + + + +} diff --git a/src/main/java/unprotesting/com/github/data/Section.java b/src/main/java/unprotesting/com/github/data/Section.java new file mode 100644 index 0000000..8d36e50 --- /dev/null +++ b/src/main/java/unprotesting/com/github/data/Section.java @@ -0,0 +1,64 @@ +package unprotesting.com.github.data; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import lombok.Getter; + +import net.kyori.adventure.text.Component; + +import org.bukkit.Material; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.inventory.ItemStack; + +import unprotesting.com.github.util.Format; + +@Getter +public class Section { + + protected final ItemStack item; + protected final boolean backEnabled; + protected final boolean enchantment; + protected final int posX; + protected final int posY; + protected final Map shops; + + /** + * Constructor for the section class. + * @param section The configuration section for the section. + */ + protected Section(String name, ConfigurationSection section) { + Material material = Material.matchMaterial(section.getString("image", "BARRIER")); + Component component = Format.getComponent(section.getString("display", "")); + ItemStack item = new ItemStack(material); + item.editMeta(meta -> meta.displayName(component)); + item.getItemMeta().lore(new ArrayList()); + this.item = item; + this.backEnabled = section.getBoolean("back-enabled", false); + this.enchantment = section.getBoolean("enchantment", false); + this.posX = section.getInt("x", 0); + this.posY = section.getInt("y", 0); + this.shops = loadShops(name); + } + + protected Map loadShops(String sectionName) { + Map shops = new HashMap(); + + for (String shopName : ShopUtil.getShopNames()) { + Shop shop = ShopUtil.getShop(shopName); + + if (shop.getSection() == null) { + Format.getLog().warning("Shop " + shopName + " has no section!"); + continue; + } + + if (shop.getSection().equalsIgnoreCase(sectionName)) { + shops.put(shopName, shop); + } + } + + return shops; + } + +} diff --git a/src/main/java/unprotesting/com/github/data/Shop.java b/src/main/java/unprotesting/com/github/data/Shop.java new file mode 100644 index 0000000..162d4f2 --- /dev/null +++ b/src/main/java/unprotesting/com/github/data/Shop.java @@ -0,0 +1,342 @@ +package unprotesting.com.github.data; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import net.kyori.adventure.text.Component; + +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.enchantments.Enchantment; +import org.bukkit.inventory.ItemStack; + +import unprotesting.com.github.config.Config; +import unprotesting.com.github.data.CollectFirst.CollectFirstSetting; +import unprotesting.com.github.util.Format; + +@Builder +@AllArgsConstructor +public class Shop implements Serializable { + + private static final long serialVersionUID = -6381163788906178955L; + + private static double M = 0.05; + private static double Z = 1.75; + + // History of buys for each time period. + protected int[] buys; + // History of sells for each time period. + protected int[] sells; + // History of prices for each time period. + protected double[] prices; + // The size of the historical data. + protected int size; + // Whether the item is an enchantment + @Getter + protected final boolean enchantment; + // The collect first setting for this shop + @Getter @Setter + protected CollectFirst setting; + // The autosell data for this shop + @Getter + protected Map autosell; + // The total buys for this shop + @Getter + protected int totalBuys; + // The total sells for this shop + @Getter + protected int totalSells; + // Whether the item is locked + @Getter + protected boolean locked; + // Whether to use a custom sell price difference + protected double customSpd; + // Whether to use a custom maxVolatility + @Getter + protected double volatility; + // Whether to use a custom volatility + @Getter + protected double change; + // The maximum buys per time period + @Getter + protected int maxBuys; + // The maximum sells per time period + @Getter + protected int maxSells; + // The update rate of the item + @Getter + protected int updateRate; + // The time since the last update + @Getter + protected int timeSinceUpdate; + // The section this shop belongs to. + @Getter + protected String section; + // The recent buys for this item + @Getter + protected Map recentBuys; + // The recent sells for this item + @Getter + protected Map recentSells; + + + /** + * Constructor for the shop class. + * @param config The configuration section for the shop. + * @param isEnchantment Whether the item is an enchantment. + */ + protected Shop(ConfigurationSection config, String sectionName, boolean isEnchantment) { + this.buys = new int[1]; + this.sells = new int[1]; + this.prices = new double[]{config.getDouble("price")}; + this.enchantment = isEnchantment; + this.size = 1; + this.totalBuys = 0; + this.totalSells = 0; + this.autosell = new HashMap(); + this.recentBuys = new HashMap(); + this.recentSells = new HashMap(); + this.setting = new CollectFirst(config.getString("collect-first", "server")); + this.loadConfiguration(config, sectionName); + } + + /** + * Load the non serialized data from the config. + * @param config The config section. + */ + protected void loadConfiguration(ConfigurationSection config, String sectionName) { + locked = config.getBoolean("locked", false); + Format.getLog().finest("Locked: " + this.locked); + customSpd = config.getDouble("sell-price-difference", -1); + Format.getLog().finest("Custom SPD: " + this.customSpd); + volatility = config.getDouble("volatility", Config.get().getVolatility()); + Format.getLog().finest("Volatility: " + this.volatility); + section = sectionName; + Format.getLog().finest("Section: " + this.section); + maxBuys = config.getInt("max-buy", -1); + Format.getLog().finest("Max Buys: " + this.maxBuys); + maxSells = config.getInt("max-sell", -1); + Format.getLog().finest("Max Sells: " + this.maxSells); + updateRate = config.getInt("update-rate", 1); + Format.getLog().finest("Update Rate: " + this.updateRate); + double startPrice = config.getDouble("price"); + + if (startPrice != prices[0]) { + prices[size - 1] = startPrice; + Format.getLog().info("Price changed for " + section + " to " + startPrice + + " because the price was changed in the config."); + } + + if (section == null) { + Format.getLog().warning("Shop " + config.getName() + " was loaded with no section!"); + } + + } + + /** + * Get the buy count for the last time period. + * @return The buy count. + */ + public int getBuyCount() { + return buys[size - 1]; + } + + /** + * Get the sell count for the last time period. + * @return The sell count. + */ + public int getSellCount() { + return sells[size - 1]; + } + + /** + * Get the price for the last time period. + * @return The price. + */ + public double getPrice() { + return prices[size - 1]; + } + + /** + * Get the sell price. + */ + public double getSellPrice() { + return getPrice() - getPrice() * getSpd() * 0.01; + } + + /** + * Add to the latest buy count. + * @param buyCount The additional buys. + */ + public void addBuys(UUID player, int buyCount) { + if (recentBuys.containsKey(player)) { + recentBuys.merge(player, buyCount, Integer::sum); + Format.getLog().finest("Recent buys: " + recentBuys.get(player)); + } else { + recentBuys.put(player, buyCount); + Format.getLog().finest("New recent buys: " + recentBuys.get(player)); + } + this.buys[size - 1] = buyCount + buys[size - 1]; + Format.getLog().finer("Increased buys by " + buyCount + " to " + buys[size - 1]); + Format.getLog().finest("Updated at time period " + (size - 1)); + + } + + /** + * Add to the latest sell count. + * @param sellCount The additional sells. + */ + public void addSells(UUID player, int sellCount) { + if (recentSells.containsKey(player)) { + recentSells.merge(player, sellCount, Integer::sum); + Format.getLog().finest("Recent sells: " + recentSells.get(player)); + } else { + recentSells.put(player, sellCount); + Format.getLog().finest("New recent sells: " + recentSells.get(player)); + } + this.sells[size - 1] = sellCount + sells[size - 1]; + Format.getLog().finer("Increased sells by " + sellCount + " to " + sells[size - 1]); + Format.getLog().finest("Updated at time period " + (size - 1)); + } + + /** + * Clear the autosell data. + */ + public void clearAutosell() { + autosell.clear(); + } + + /** + * Increase the autosell count for a uuid. + * @param uuid The uuid. + * @param count The count. + */ + public void addAutosell(UUID uuid, int count) { + if (autosell.containsKey(uuid)) { + autosell.merge(uuid, count, Integer::sum); + Format.getLog().finest("Autosell: " + autosell.get(uuid) + " for " + uuid); + } else { + autosell.put(uuid, count); + Format.getLog().finest("New autosell: " + autosell.get(uuid) + " for " + uuid); + } + } + + /** + * Calculates if a given player has unlocked this item. + * @return Whether the player has unlocked this item. + */ + public boolean isUnlocked(UUID player) { + if (setting.getSetting().equals(CollectFirstSetting.SERVER)) { + return setting.isFoundInServer(); + } else if (setting.getSetting().equals(CollectFirstSetting.PLAYER)) { + return setting.playerFound(player); + } else { + return true; + } + } + + private double getSpd() { + if (customSpd != -1) { + return customSpd; + } + return Config.get().getSellPriceDifference(); + } + + /** + * Create a new time period for the shop. + * @param price The new price for the time period. + */ + public void timePeriod(double price) { + + int[] newBuys = new int[size + 1]; + int[] newSells = new int[size + 1]; + double[] newPrices = new double[size + 1]; + + this.totalBuys += buys[size - 1]; + this.totalSells += sells[size - 1]; + + for (int i = 0; i < size; i++) { + newBuys[i] = buys[i]; + newSells[i] = sells[i]; + newPrices[i] = prices[i]; + } + + newBuys[size] = 0; + newSells[size] = 0; + double newPrice = prices[size - 1]; + + if (!locked && updateRate > 0) { + if (timeSinceUpdate >= updateRate) { + newPrice = price; + this.timeSinceUpdate = 0; + this.recentBuys.clear(); + this.recentSells.clear(); + } + this.timeSinceUpdate++; + } + + newPrices[size] = newPrice; + this.buys = newBuys; + this.sells = newSells; + this.prices = newPrices; + this.size++; + } + + /** + * Update the percentage change for the shop. + */ + protected void updateChange() { + + if (locked || size < 2) { + return; + } + + int dailyTimePeriods = (int) Math.floor(1f / (Config.get().getTimePeriod() / 1440f)); + int start = size - dailyTimePeriods > 0 ? size - dailyTimePeriods : 0; + this.change = (prices[size - 1] - prices[start]) / prices[start]; + } + + /** + * Loads the buy vs sell strength for the shop. + */ + public double strength() { + int x = 0; + int y = 1; + double buy = 0; + double sell = 0; + + while (y <= size) { + buy += buys[size - y]; + sell += sells[size - y]; + x++; + y = (int) Math.round(M * Math.pow(x, Z) + 0.5); + } + + if (buy == 0 && sell == 0) { + return 0; + } + + return (buy - sell) / (buy + sell); + } + + /** + * Get the display name for this shop. + */ + protected static Component getDisplayName(String name, boolean isEnchantment) { + name = name.toLowerCase(); + + if (isEnchantment) { + return Enchantment.getByKey(NamespacedKey.minecraft(name)).displayName(1); + } + + return new ItemStack(Material.matchMaterial(name)).displayName(); + } + +} diff --git a/src/main/java/unprotesting/com/github/data/ShopSerializer.java b/src/main/java/unprotesting/com/github/data/ShopSerializer.java new file mode 100644 index 0000000..d62e711 --- /dev/null +++ b/src/main/java/unprotesting/com/github/data/ShopSerializer.java @@ -0,0 +1,116 @@ +package unprotesting.com.github.data; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.mapdb.DataInput2; +import org.mapdb.DataOutput2; +import org.mapdb.Serializer; + +public class ShopSerializer implements Serializer { + + @Override + public void serialize(DataOutput2 out, Shop value) throws IOException { + out.writeInt(value.size); + + for (int i = 0; i < value.size; i++) { + out.writeInt(value.buys[i]); + out.writeInt(value.sells[i]); + out.writeDouble(value.prices[i]); + } + + out.writeBoolean(value.enchantment); + new CollectFirstSerializer().serialize(out, value.setting); + out.writeInt(value.autosell.size()); + + for (Map.Entry entry : value.autosell.entrySet()) { + UUID.serialize(out, entry.getKey()); + out.writeInt(entry.getValue()); + } + + out.writeInt(value.totalBuys); + out.writeInt(value.totalSells); + out.writeBoolean(value.locked); + + if (value.customSpd == -1) { + out.writeBoolean(false); + } else { + out.writeBoolean(true); + out.writeDouble(value.customSpd); + } + + out.writeDouble(value.volatility); + out.writeDouble(value.change); + out.writeInt(value.maxBuys); + out.writeInt(value.maxSells); + out.writeInt(value.updateRate); + out.writeInt(value.timeSinceUpdate); + out.writeUTF(value.section); + out.writeInt(value.recentBuys.size()); + + for (Map.Entry entry : value.recentBuys.entrySet()) { + UUID.serialize(out, entry.getKey()); + out.writeInt(entry.getValue()); + } + + out.writeInt(value.recentSells.size()); + + for (Map.Entry entry : value.recentSells.entrySet()) { + UUID.serialize(out, entry.getKey()); + out.writeInt(entry.getValue()); + } + + } + + @Override + public Shop deserialize(DataInput2 input, int available) throws IOException { + Shop.ShopBuilder builder = new Shop.ShopBuilder(); + int size = input.readInt(); + builder.size(size); + int[] buys = new int[size]; + int[] sells = new int[size]; + double[] prices = new double[size]; + for (int i = 0; i < size; i++) { + buys[i] = input.readInt(); + sells[i] = input.readInt(); + prices[i] = input.readDouble(); + } + builder.buys(buys); + builder.sells(sells); + builder.prices(prices); + builder.enchantment(input.readBoolean()); + builder.setting(new CollectFirstSerializer().deserialize(input, available)); + int autosellSize = input.readInt(); + Map autosell = new HashMap<>(); + for (int i = 0; i < autosellSize; i++) { + autosell.put(UUID.deserialize(input, available), input.readInt()); + } + builder.autosell(autosell); + builder.totalBuys(input.readInt()); + builder.totalSells(input.readInt()); + builder.locked(input.readBoolean()); + builder.customSpd(input.readBoolean() ? input.readDouble() : -1); + builder.volatility(input.readDouble()); + builder.change(input.readDouble()); + builder.maxBuys(input.readInt()); + builder.maxSells(input.readInt()); + builder.updateRate(input.readInt()); + builder.timeSinceUpdate(input.readInt()); + builder.section(input.readUTF()); + int recentBuysSize = input.readInt(); + Map recentBuys = new HashMap<>(); + for (int i = 0; i < recentBuysSize; i++) { + recentBuys.put(UUID.deserialize(input, available), input.readInt()); + } + builder.recentBuys(recentBuys); + int recentSellsSize = input.readInt(); + Map recentSells = new HashMap<>(); + for (int i = 0; i < recentSellsSize; i++) { + recentSells.put(UUID.deserialize(input, available), input.readInt()); + } + builder.recentSells(recentSells); + return builder.build(); + } +} diff --git a/src/main/java/unprotesting/com/github/data/ShopUtil.java b/src/main/java/unprotesting/com/github/data/ShopUtil.java new file mode 100644 index 0000000..7b3a83a --- /dev/null +++ b/src/main/java/unprotesting/com/github/data/ShopUtil.java @@ -0,0 +1,73 @@ +package unprotesting.com.github.data; + +import org.bukkit.OfflinePlayer; + +public class ShopUtil { + + protected static String[] sectionNameCache; + protected static String[] shopNameCache; + + public static Shop getShop(String item) { + return Database.get().getShop(item); + } + + public static void putShop(String key, Shop shop) { + Database.get().putShop(key, shop); + } + + /** + * Get the list of possible shop names. + * @return The list of possible shop names. + */ + public static String[] getShopNames() { + if (shopNameCache == null) { + shopNameCache = Database.get().getShopNames(); + } + return shopNameCache; + } + + /** + * Get the list of possible section names. + * @return The list of possible section names. + */ + public static String[] getSectionNames() { + if (sectionNameCache == null) { + sectionNameCache = Database.get().sections.keySet().toArray(new String[0]); + } + return sectionNameCache; + } + + /** + * Get a section of the shop. + * @param name The name of the section. + * @return The section. + */ + public static Section getSection(String name) { + + if (Database.get().sections.containsKey(name)) { + return Database.get().sections.get(name); + } + + for (String sectionName : getSectionNames()) { + if (sectionName.equalsIgnoreCase(name)) { + return Database.get().sections.get(sectionName); + } + } + + return null; + } + + public static int getBuysLeft(OfflinePlayer player, String item) { + return Database.get().getPurchasesLeft(item, player.getUniqueId(), true); + } + + public static int getSellsLeft(OfflinePlayer player, String item) { + return Database.get().getPurchasesLeft(item, player.getUniqueId(), false); + } + + public static void addTransaction(Transaction transaction) { + Database.get().transactions.put(System.currentTimeMillis(), transaction); + } + + +} diff --git a/src/main/java/unprotesting/com/github/data/Transaction.java b/src/main/java/unprotesting/com/github/data/Transaction.java new file mode 100644 index 0000000..f2ce36c --- /dev/null +++ b/src/main/java/unprotesting/com/github/data/Transaction.java @@ -0,0 +1,28 @@ +package unprotesting.com.github.data; + +import java.io.Serializable; +import java.util.UUID; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +@AllArgsConstructor +@Data +@Builder +public class Transaction implements Serializable { + + private static final long serialVersionUID = -7234917640151336711L; + + private double price; + private int amount; + private UUID player; + private String item; + private TransactionType position; + + public static enum TransactionType { + BUY, + SELL + } + +} diff --git a/src/main/java/unprotesting/com/github/data/TransactionSerializer.java b/src/main/java/unprotesting/com/github/data/TransactionSerializer.java new file mode 100644 index 0000000..a2437d7 --- /dev/null +++ b/src/main/java/unprotesting/com/github/data/TransactionSerializer.java @@ -0,0 +1,32 @@ +package unprotesting.com.github.data; + +import java.io.IOException; + +import org.mapdb.DataInput2; +import org.mapdb.DataOutput2; +import org.mapdb.Serializer; + +import unprotesting.com.github.data.Transaction.TransactionType; + +public class TransactionSerializer implements Serializer { + + @Override + public void serialize(DataOutput2 out, Transaction value) throws IOException { + out.writeDouble(value.getPrice()); + out.writeInt(value.getAmount()); + UUID.serialize(out, value.getPlayer()); + out.writeUTF(value.getItem()); + out.writeUTF(value.getPosition().toString()); + } + + @Override + public Transaction deserialize(DataInput2 in, int available) throws IOException { + Transaction.TransactionBuilder builder = new Transaction.TransactionBuilder(); + builder.price(in.readDouble()); + builder.amount(in.readInt()); + builder.player(UUID.deserialize(in, available)); + builder.item(in.readUTF()); + builder.position(TransactionType.valueOf(in.readUTF())); + return builder.build(); + } +} diff --git a/src/main/java/unprotesting/com/github/data/csv/CsvHandler.java b/src/main/java/unprotesting/com/github/data/csv/CsvHandler.java deleted file mode 100644 index 3dba8ac..0000000 --- a/src/main/java/unprotesting/com/github/data/csv/CsvHandler.java +++ /dev/null @@ -1,97 +0,0 @@ -package unprotesting.com.github.data.csv; - -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -import unprotesting.com.github.Main; -import unprotesting.com.github.config.Config; -import unprotesting.com.github.data.persistent.TimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.EnchantmentsTimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.GdpTimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.ItemTimePeriod; - -public class CsvHandler { - - /** - * Creates a CSV file with all price, buy and sell data to be read by the webpage. - */ - public static void writeCsv() { - - try { - write("trade.csv", 0); - } catch (IOException e) { - Main.getInstance().getLogger().severe("Could not write to csv file."); - } - - } - - /** - * Write the latest x rows of price data. - * @param fileName The name of the file to write to. - * @param rows The number of rows to write. - */ - private static void write(String fileName, int rows) throws IOException { - FileWriter fileStream = new FileWriter(Config.getConfig().getDataLocation() + fileName); - BufferedWriter writer = new BufferedWriter(fileStream); - int size = Main.getInstance().getDatabase().getMap().size(); - TimePeriod tp = Main.getInstance().getDatabase().getMap().get(size - 1); - List items = Arrays.asList(tp.getItemTP().getItems()); - List enchantments = Arrays.asList(tp.getEnchantmentsTP().getItems()); - writer.write("GDP,Balance,Debt,Loss,Inflation"); - - if (rows == -1) { - rows = size; - } - - for (String item : items) { - writer.write(item + ","); - } - - if (Config.getConfig().isEnableEnchantments()) { - for (String enchantment : enchantments) { - writer.write(enchantment.toUpperCase() + ","); - } - } - - writer.write("\n"); - - for (int i = (size - rows); i < size; i++) { - GdpTimePeriod gtp = Main.getInstance().getDatabase().getMap().get(i).getGdpTP(); - - writer.write(gtp.getGdp() + "," - + gtp.getBalance() + "," - + gtp.getDebt() + "," - + gtp.getLoss() + "," - + gtp.getInflation()); - - ItemTimePeriod itp = Main.getInstance().getDatabase().getMap().get(i).getItemTP(); - - EnchantmentsTimePeriod etp = Main.getInstance() - .getDatabase().getMap().get(i).getEnchantmentsTP(); - - if (itp == null) { - continue; - } - - for (int j = 0; j < itp.getItems().length; j++) { - writer.write("," + itp.getPrices()[j]); - } - - if (Config.getConfig().isEnableEnchantments()) { - - for (int j = 0; j < etp.getItems().length; j++) { - writer.write("," + etp.getPrices()[j]); - } - - } - - } - - writer.close(); - - } - -} diff --git a/src/main/java/unprotesting/com/github/data/ephemeral/LocalDataCache.java b/src/main/java/unprotesting/com/github/data/ephemeral/LocalDataCache.java deleted file mode 100644 index f3cd903..0000000 --- a/src/main/java/unprotesting/com/github/data/ephemeral/LocalDataCache.java +++ /dev/null @@ -1,707 +0,0 @@ -package unprotesting.com.github.data.ephemeral; - -import java.text.DecimalFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import lombok.Data; -import lombok.SneakyThrows; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.OfflinePlayer; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.entity.Player; - -import unprotesting.com.github.Main; -import unprotesting.com.github.commands.objects.Section; -import unprotesting.com.github.config.Config; -import unprotesting.com.github.config.Messages; -import unprotesting.com.github.data.ephemeral.data.EconomyInfoData; -import unprotesting.com.github.data.ephemeral.data.EnchantmentData; -import unprotesting.com.github.data.ephemeral.data.GdpData; -import unprotesting.com.github.data.ephemeral.data.ItemData; -import unprotesting.com.github.data.ephemeral.data.LoanData; -import unprotesting.com.github.data.ephemeral.data.MaxBuySellData; -import unprotesting.com.github.data.ephemeral.data.TransactionData; -import unprotesting.com.github.data.ephemeral.other.PlayerSaleData; -import unprotesting.com.github.data.ephemeral.other.Sale; -import unprotesting.com.github.data.ephemeral.other.Sale.SalePositionType; -import unprotesting.com.github.data.persistent.TimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.EnchantmentsTimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.GdpTimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.ItemTimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.LoanTimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.TransactionsTimePeriod; -import unprotesting.com.github.util.UtilFunctions; - -@Data -public class LocalDataCache { - - private HashMap items; - private HashMap enchantments; - private List loans; - private List newLoans; - private List transactions; - private List newTransactions; - private HashMap playerSales; - private List
sections; - private HashMap maxPurchases; - private HashMap percentageChanges; - private GdpData gdpData; - private EconomyInfoData economyInfo; - private int size; - - /** - * Initializes the local data cache. - */ - public LocalDataCache() { - this.items = new HashMap(); - this.enchantments = new HashMap(); - this.loans = new ArrayList(); - this.newLoans = new ArrayList(); - this.transactions = new ArrayList(); - this.newTransactions = new ArrayList(); - this.playerSales = new HashMap(); - this.sections = new ArrayList
(); - this.maxPurchases = new HashMap(); - this.percentageChanges = new HashMap(); - this.size = Main.getInstance().getDatabase().getMap().size(); - init(); - } - - /** - * Add a new sale to related maps. - * @param uuid The player's uuid. - * @param item The item being sold. - * @param price The price of the item. - * @param amount The amount of the item being sold. - * @param position The sale position type of the sale. - */ - public void addSale(UUID uuid, String item, double price, int amount, SalePositionType position) { - - OfflinePlayer player = Bukkit.getOfflinePlayer(uuid); - PlayerSaleData playerSaleData = getPlayerSaleData(player); - playerSaleData.addSale(item, amount, position); - playerSales.put(player.getUniqueId().toString(), playerSaleData); - addSale(new TransactionData(uuid.toString(), item, amount, price, position)); - - } - - /** - * Add an item sale to map. - * @param transaction The transaction to add to the map. - */ - private void addSale(TransactionData transaction) { - - ItemData itemData = items.get(transaction.getItem()); - EnchantmentData enchantmentData = enchantments.get(transaction.getItem()); - - switch (transaction.getPosition()) { - - case BUY: - - itemData.increaseBuys(transaction.getAmount()); - items.put(transaction.getItem(), itemData); - break; - - case SELL: - - gdpData.increaseLoss((transaction.getAmount() * getItemPrice(transaction.getItem(), false)) - - (transaction.getAmount() * transaction.getPrice())); - - itemData.increaseSells(transaction.getAmount()); - items.put(transaction.getItem(), itemData); - break; - - case EBUY: - - enchantmentData.increaseBuys(transaction.getAmount()); - enchantments.put(transaction.getItem(), enchantmentData); - break; - - case ESELL: - - gdpData.increaseLoss((transaction.getAmount() * getItemPrice(transaction.getItem(), false)) - - (transaction.getAmount() * transaction.getPrice())); - - enchantmentData.increaseSells(transaction.getAmount()); - enchantments.put(transaction.getItem(), enchantmentData); - break; - - default: - return; - } - - transactions.add(transaction); - newTransactions.add(transaction); - gdpData.increaseGdp(transaction.getAmount() * transaction.getPrice() / 2); - - } - - /** - * Add new loan to ephemeral cache. - * @param value The value of the loan. - * @param interestRate The interest rate of the loan. - * @param player The player who is borrowing. - */ - public void addLoan(double value, double interestRate, OfflinePlayer player) { - - LoanData data = new LoanData(value, interestRate, player.getUniqueId().toString()); - loans.add(data); - newLoans.add(data); - - // If the player is online then return. - if (!player.isOnline()) { - return; - } - - Player onlinePlayer = player.getPlayer(); - DecimalFormat df = UtilFunctions.getDf(); - double minutelyUpdateRate = Config.getConfig().getInterestRateUpdateRate() / 1200; - - TagResolver resolver = TagResolver.resolver( - - Placeholder.unparsed("total", df.format(value)), - Placeholder.unparsed("interest", df.format(interestRate)), - Placeholder.unparsed("update-rate", df.format(minutelyUpdateRate)) - - ); - - Component message = Main.getInstance().getMm().deserialize( - Messages.getMessages().getLoanSuccess(), resolver); - - onlinePlayer.sendMessage(message); - - Collections.sort(loans); - - } - - /** - * Get the price of an item. - * @param item The item to get the price of. - * @param sell Whether the item is being sold or bought. - * @return The price of the item. - */ - public double getItemPrice(String item, boolean sell) { - - ItemData data = items.get(item); - - // If the itemData is null then return. - if (data == null) { - return 0; - } - - // If the item is being bought then return the price. - if (!sell) { - return data.getPrice(); - } - - Double spd = Config.getConfig().getSellPriceDifference(); - - // If a custom sell price difference is set then set the spd to the custom value. - if (Main.getInstance().getDataFiles().getShops().getConfigurationSection( - "shops").getConfigurationSection(item).contains("sell-difference")) { - - spd = Main.getInstance().getDataFiles().getShops().getConfigurationSection( - "shops").getConfigurationSection(item).getDouble("sell-difference"); - - } - - return (data.getPrice() - data.getPrice() * spd * 0.01); - - } - - /** - * Get the price of an enchantment. - * @param enchantment The enchantment to get the price of. - * @param sell Whether the enchantment is being sold or bought. - * @return The price of the enchantment. - */ - public double getEnchantmentPrice(String enchantment, boolean sell) { - - EnchantmentData data = enchantments.get(enchantment); - - // If the enchantmentData is null then return. - if (data == null) { - return 0; - } - - // If the enchantment is being bought then return the price. - if (!sell) { - return data.getPrice(); - } - - Double spd = Config.getConfig().getSellPriceDifference(); - - // If a custom sell price difference is set then set the spd to the custom value. - if (Main.getInstance().getDataFiles().getEnchantments().getConfigurationSection( - "enchantments").getConfigurationSection(enchantment).contains("sell-difference")) { - - spd = Main.getInstance().getDataFiles().getEnchantments().getConfigurationSection( - "enchantments").getConfigurationSection(enchantment).getDouble("sell-difference"); - - } - - return (data.getPrice() - data.getPrice() * spd * 0.01); - - } - - /** - * Get the enchantment ratio of an enchantment. - * @param enchantment The enchantment to get the ratio of. - * @return The enchantment ratio. - */ - public double getEnchantmentRatio(String enchantment) { - - EnchantmentData data = enchantments.get(enchantment); - - // If the enchantmentData is null then return. - if (data == null) { - return 0; - } - - return data.getRatio(); - - } - - /** - * Get price of an item with an enchantment. - * @param enchantment The enchantment to get the price of. - * @param itemPrice The price of the item. - * @param sell Whether the item is being sold or bought. - * @return The price of the item with the enchantment. - */ - public double getOverallEnchantmentPrice(String enchantment, double itemPrice, boolean sell) { - - double price = getEnchantmentPrice(enchantment, sell); - double ratio = getEnchantmentRatio(enchantment); - double total = price + (itemPrice * ratio); - total -= (total * Config.getConfig().getEnchantmentLimiter() * 0.01); - return itemPrice + total; - - } - - /** - * Get the amount of buys or sells left for an item. - * @param item The item to get the amount of buys or sells left for. - * @param player The player to get the amount of buys or sells left for. - * @param isBuys Whether the amount of buys or sells left is being requested. - * @return The amount of buys or sells left for the item. - */ - public int getPurchasesLeft(String item, OfflinePlayer player, boolean isBuys) { - - int defaultMax = 99999; - PlayerSaleData saleData = playerSales.getOrDefault(player.getUniqueId().toString(), null); - MaxBuySellData maxData = maxPurchases.get(item); - - // If the saleData or maxData is null then return the default max. - // If "disable-max-buys-sells" is true then return the default max. - if (maxData == null || Config.getConfig().isDisableMaxBuysSells()) { - return defaultMax; - } - - if (saleData == null) { - if (isBuys) { - return maxData.getBuys(); - } else { - return maxData.getSells(); - } - } - - int maxBuys = maxData.getBuys(); - int maxSells = maxData.getSells(); - int buys = countSales(saleData.getBuys(), item); - int sells = countSales(saleData.getSells(), item); - - // If the player is buying then return the maxBuys - buys. - // If the player is selling then return the maxSells - sells. - if (isBuys) { - return maxBuys - buys; - } else { - return maxSells - sells; - } - - } - - /** - * Get the amount of sales for an item. - * @param sales The sales to get the amount of sales for. - * @return The amount of sales for the item. - */ - private int countSales(List sales, String item) { - int amount = 0; - for (Sale sale : sales) { - if (!sale.getItem().equals(item)) { - continue; - } - amount += sale.getAmount(); - } - return amount; - } - - /** - * Get the percentage change string for an item. - * @param item The item to get the percentage change string for. - * @return The percentage change string for the item. - */ - public String getChangeString(String item) { - - DecimalFormat df = new DecimalFormat(Config.getConfig().getNumberFormat()); - Double change = percentageChanges.get(item); - - if (change == null) { - return (ChatColor.GRAY + "0.0%"); - } - - if (change < -0.005) { - return (ChatColor.RED + df.format(change) + "%"); - } - - if (change > 0.005) { - return (ChatColor.GREEN + df.format(change) + "%"); - } else { - return (ChatColor.GRAY + "0.0%"); - } - - } - - /** - * Update percentage changes for all items. - */ - public void updatePercentageChanges() { - - // If the size is 1 or 2 then return. - if (size < 2) { - return; - } - - int tpInDay = (int) Math.floor(1.0 / (Config.getConfig().getTimePeriod() / 1440.0)); - int base = size - tpInDay > 0 ? size - tpInDay : 0; - TimePeriod timePeriodLatest = Main.getInstance().getDatabase().getMap().get((size - 1)); - TimePeriod timePeriodBase = Main.getInstance().getDatabase().getMap().get(base); - ItemTimePeriod itemLatest = timePeriodLatest.getItemTP(); - ItemTimePeriod itemBase = timePeriodBase.getItemTP(); - EnchantmentsTimePeriod enchantmentLatest = timePeriodLatest.getEnchantmentsTP(); - EnchantmentsTimePeriod enchantmentBase = timePeriodBase.getEnchantmentsTP(); - - - // Loop through all items. - for (String item : itemLatest.getItems()) { - - int latestPosition = Arrays.asList(itemLatest.getItems()).indexOf(item); - int basePosition = Arrays.asList(itemBase.getItems()).indexOf(item); - double latestPrice = itemLatest.getPrices()[latestPosition]; - double basePrice = itemBase.getPrices()[basePosition]; - double change = (latestPrice - basePrice) / basePrice * 100; - percentageChanges.put(item, change); - - } - - // Loop through all enchantments. - for (String enchantment : enchantmentLatest.getItems()) { - - int latestPosition = Arrays.asList(enchantmentLatest.getItems()).indexOf(enchantment); - int basePosition = Arrays.asList(enchantmentBase.getItems()).indexOf(enchantment); - double latestPrice = enchantmentLatest.getPrices()[latestPosition]; - double basePrice = enchantmentBase.getPrices()[basePosition]; - double change = (latestPrice - basePrice) / basePrice * 100; - percentageChanges.put(enchantment, change); - - } - - } - - /** - * Initialize cache from database and files. - */ - private void init() { - - loadShopDataFromFile(); - loadShopDataFromData(); - loadEnchantmentDataFromFile(); - loadLoanDataFromData(); - loadTransactionDataFromData(); - loadSectionDataFromFile(); - loadGdpDataFromData(); - loadEconomyInfoDataFromFile(); - loadEconomyInfoDataFromData(); - updatePercentageChanges(); - - } - - /** - * Get the current cache for the PlayerSaleData object. - * @param player The player to get the PlayerSaleData object for. - * @return The PlayerSaleData object for the player. - */ - private PlayerSaleData getPlayerSaleData(OfflinePlayer player) { - return playerSales.getOrDefault(player.getUniqueId().toString(), new PlayerSaleData()); - } - - /** - * Load the default shops and data from the files. - */ - private void loadShopDataFromFile() { - - ConfigurationSection config = Main.getInstance().getDataFiles() - .getShops().getConfigurationSection("shops"); - - Set set = config.getKeys(false); - - // Loop through keys in shops section of config file. - for (String key : set) { - - ConfigurationSection section = config.getConfigurationSection(key); - - // If the material is not a valid material, skip it and throw an error. - if (Material.matchMaterial(key) == null) { - - Main.getInstance().getLogger().severe("Invalid item in shops.yml: " + key); - continue; - - } - - ItemData data = new ItemData(section.getDouble("price", 0.0)); - - MaxBuySellData maxBuySellData = new MaxBuySellData( - section.getInt("max-buy", 99999), section.getInt("max-sell", 99999)); - - maxPurchases.put(key, maxBuySellData); - items.put(key, data); - - } - - } - - private void loadShopDataFromData() { - - // If the size is less than 2 set the percentage changes to 0. - if (size < 2) { - - for (String str : items.keySet()) { - percentageChanges.put(str, 0.0); - } - - for (String str : enchantments.keySet()) { - percentageChanges.put(str, 0.0); - } - - } - - // if the size is 0 return. - if (size == 0) { - return; - } - - ItemTimePeriod itp = Main.getInstance().getDatabase().getMap().get(size - 1).getItemTP(); - - EnchantmentsTimePeriod etp = Main.getInstance() - .getDatabase().getMap().get(size - 1).getEnchantmentsTP(); - - // Loop through all items. - for (int i = 0; i < itp.getItems().length; i++) { - - String item = itp.getItems()[i]; - ItemData data = new ItemData(itp.getPrices()[i]); - items.put(item, data); - - } - - // Loop through all enchantments. - for (int i = 0; i < etp.getItems().length; i++) { - - String enchantment = etp.getItems()[i]; - EnchantmentData data = new EnchantmentData(etp.getPrices()[i], etp.getRatios()[i]); - enchantments.put(enchantment, data); - - } - - } - - private void loadEnchantmentDataFromFile() { - - ConfigurationSection config = Main.getInstance().getDataFiles() - .getEnchantments().getConfigurationSection("enchantments"); - - Set set = config.getKeys(false); - - // Loop through keys in enchantments section of config file. - for (String key : set) { - - // If the enchantment is not a valid enchantment, skip it and throw an error. - if (NamespacedKey.minecraft(key.toLowerCase()) == null) { - Main.getInstance().getLogger().severe("Invalid enchantment in enchantments.yml: " + key); - continue; - } - - ConfigurationSection sec = config.getConfigurationSection(key); - - EnchantmentData data = new EnchantmentData( - sec.getDouble("price", 0.0), sec.getDouble("ratio", 0.0)); - - enchantments.put(key, data); - - } - } - - private void loadLoanDataFromData() { - - // If the size is less than 1 return. - if (size < 1) { - return; - } - - loans.clear(); - - // Loop through all time periods. - for (Integer pos : Main.getInstance().getDatabase().getMap().keySet()) { - - LoanTimePeriod ltp = Main.getInstance().getDatabase().getMap().get(pos).getLoanTP(); - - // Loop through all loans. - for (int i = 0; i < ltp.getValues().length; i++) { - - LoanData data = new LoanData(ltp.getValues()[i], ltp.getInterestRates()[i], - ltp.getPlayers()[i], ltp.getTime()[i]); - - loans.add(data); - - } - - } - - Collections.sort(loans); - - } - - // Map of legacy position types to new position types. - private static final Map legacyPositionTypes = new HashMap() { - - { - - put("BI", "BUY"); - put("SI", "SELL"); - put("BE", "EBUY"); - put("SE", "ESELL"); - - } - - }; - - @SneakyThrows - private void loadTransactionDataFromData() { - - // If the size is less than 1 return. - if (size < 1) { - return; - } - - transactions.clear(); - - // Loop through all time periods. - for (Integer pos : Main.getInstance().getDatabase().getMap().keySet()) { - - TransactionsTimePeriod ttp = Main.getInstance().getDatabase() - .getMap().get(pos).getTransactionsTP(); - - // Loop through all transactions. - for (int i = 0; i < ttp.getPrices().length; i++) { - - SalePositionType position; - - try { - position = SalePositionType.valueOf(ttp.getPositions()[i]); - } catch (Exception e) { - - // If the position is not a valid position, check if it is a legacy position. - if (legacyPositionTypes.containsKey(ttp.getPositions()[i])) { - ttp.getPositions()[i] = legacyPositionTypes.get(ttp.getPositions()[i]); - position = SalePositionType.valueOf(ttp.getPositions()[i]); - } else { - - Main.getInstance().getLogger().severe( - "Invalid position in transaction data: " + ttp.getPositions()[i]); - - continue; - } - - - } - - - - - TransactionData data = new TransactionData(ttp.getPlayers()[i], ttp.getItems()[i], - ttp.getAmounts()[i], ttp.getPrices()[i], position, ttp.getTime()[i]); - - transactions.add(data); - - } - - } - - Collections.sort(transactions); - - } - - private void loadSectionDataFromFile() { - - ConfigurationSection config = Main.getInstance().getDataFiles().getShops() - .getConfigurationSection("sections"); - - // Loop through all keys in config file and add section data to map. - for (String key : config.getKeys(false)) { - sections.add(new Section(config.getConfigurationSection(key), key)); - } - - config = Main.getInstance().getDataFiles().getEnchantments().getConfigurationSection("config"); - sections.add(new Section(config, "Enchantments")); - - } - - private void loadGdpDataFromData() { - - // If the size is less than 1 initialize the gdpData object. - if (size < 1) { - - gdpData = new GdpData(0, 0, 0, 0, 0, 0); - return; - - } - - GdpTimePeriod gtp = Main.getInstance().getDatabase().getMap().get(size - 1).getGdpTP(); - - gdpData = new GdpData(gtp.getGdp(), gtp.getBalance(), gtp.getLoss(), - gtp.getDebt(), gtp.getInflation(), gtp.getPlayerCount()); - - } - - private void loadEconomyInfoDataFromFile() { - economyInfo = new EconomyInfoData(Config.getConfig().getSellPriceDifferenceVariationStart()); - } - - private void loadEconomyInfoDataFromData() { - - // If the size is less than 1 return. - if (size < 1) { - return; - } - - economyInfo = new EconomyInfoData(Main.getInstance().getDatabase() - .getMap().get(size - 1).getEconomyInfoTP().getSellPriceDifference()); - - } - -} diff --git a/src/main/java/unprotesting/com/github/data/ephemeral/data/AutosellData.java b/src/main/java/unprotesting/com/github/data/ephemeral/data/AutosellData.java deleted file mode 100644 index c637e1a..0000000 --- a/src/main/java/unprotesting/com/github/data/ephemeral/data/AutosellData.java +++ /dev/null @@ -1,37 +0,0 @@ -package unprotesting.com.github.data.ephemeral.data; - -import java.util.concurrent.ConcurrentHashMap; - -import lombok.Getter; - -public class AutosellData { - - @Getter - private ConcurrentHashMap data; - - /** - * Initializes the autosell data. - */ - public AutosellData() { - data = new ConcurrentHashMap(); - } - - /** - * Add a new item to the autosell data. - * @param uuid The player's uuid. - * @param amount The amount of the item. - */ - public void add(String uuid, Double amount) { - - // If the item already exists, add the amount to the existing amount. - // Otherwise, add the item to the data. - if (data.containsKey(uuid)) { - data.put(uuid, data.get(uuid) + amount); - return; - } else { - data.put(uuid, amount); - } - - } - -} diff --git a/src/main/java/unprotesting/com/github/data/ephemeral/data/EconomyInfoData.java b/src/main/java/unprotesting/com/github/data/ephemeral/data/EconomyInfoData.java deleted file mode 100644 index e25585b..0000000 --- a/src/main/java/unprotesting/com/github/data/ephemeral/data/EconomyInfoData.java +++ /dev/null @@ -1,28 +0,0 @@ -package unprotesting.com.github.data.ephemeral.data; - -import lombok.Getter; -import unprotesting.com.github.config.Config; - -public class EconomyInfoData { - - @Getter - private double sellPriceDifference; - - /** - * Initializes the economy info data. - */ - public EconomyInfoData(double sellPriceDifference) { - this.sellPriceDifference = sellPriceDifference; - Config.getConfig().setSellPriceDifference(this.sellPriceDifference); - } - - /** - * Updates the sell price difference. - * @param newSpd The new sell price difference. - */ - public void updateSellPriceDifference(double newSpd) { - sellPriceDifference = newSpd; - Config.getConfig().setSellPriceDifference(newSpd); - } - -} diff --git a/src/main/java/unprotesting/com/github/data/ephemeral/data/EnchantmentData.java b/src/main/java/unprotesting/com/github/data/ephemeral/data/EnchantmentData.java deleted file mode 100644 index 72b3e8a..0000000 --- a/src/main/java/unprotesting/com/github/data/ephemeral/data/EnchantmentData.java +++ /dev/null @@ -1,44 +0,0 @@ -package unprotesting.com.github.data.ephemeral.data; - -import lombok.Getter; -import lombok.Setter; - -@Getter -public class EnchantmentData { - - private int buys; - private int sells; - @Setter - private double price; - @Setter - private double ratio; - - /** - * Initializes the enchantment data. - */ - public EnchantmentData(double price, double ratio) { - - this.buys = 0; - this.sells = 0; - this.price = price; - this.ratio = ratio; - - } - - /** - * Increases the buy amount. - * @param amount The amount to increase by. - */ - public void increaseBuys(int amount) { - buys += amount; - } - - /** - * Increases the sell amount. - * @param amount The amount to increase by. - */ - public void increaseSells(int amount) { - sells += amount; - } - -} diff --git a/src/main/java/unprotesting/com/github/data/ephemeral/data/GdpData.java b/src/main/java/unprotesting/com/github/data/ephemeral/data/GdpData.java deleted file mode 100644 index e59197f..0000000 --- a/src/main/java/unprotesting/com/github/data/ephemeral/data/GdpData.java +++ /dev/null @@ -1,122 +0,0 @@ -package unprotesting.com.github.data.ephemeral.data; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; - -import unprotesting.com.github.Main; -import unprotesting.com.github.economy.EconomyFunctions; - -@Getter -public class GdpData { - - @Setter - private double gdp; - @Setter - private double balance; - @Setter - private double debt; - @Setter - private double loss; - @Setter - private double inflation; - private int playerCount; - - /** - * Initializes the GDP data. - */ - public GdpData(double gdp, double balance, double loss, - double debt, double inflation, int playerCount) { - - this.gdp = gdp; - this.loss = loss; - this.balance = balance; - this.playerCount = playerCount; - this.debt = debt; - this.inflation = inflation; - - } - - /** - * Increases the GDP. - * @param amount The amount to increase by. - */ - public void increaseGdp(double amount) { - gdp += amount; - } - - /** - * Increases the loss. - * @param amount The amount to increase by. - */ - public void increaseLoss(double amount) { - loss += amount; - } - - /** - * Update the server total balance. - */ - public void updateBalance() { - - double serverBalance = 0; - int serverPlayerCount = 0; - - // Loop through all joined players. - for (OfflinePlayer player : Bukkit.getOfflinePlayers()) { - - // If the player is null, continue. - if (player == null) { - continue; - } - - try { - serverBalance += EconomyFunctions.getEconomy().getBalance(player); - serverPlayerCount++; - } catch (Exception e) { - return; - } - - } - - balance = serverBalance; - playerCount = serverPlayerCount; - - } - - /** - * Update the server debt. - */ - public void updateDebt() { - - double serverDebt = 0; - - // Loop through loans and add value to server debt. - for (LoanData data : Main.getInstance().getCache().getLoans()) { - serverDebt += data.getValue(); - } - - debt = serverDebt; - - } - - /** - * Update the server inflation. - */ - public void updateInflation() { - - double inflationTotal = 0.0; - double i = 0; - - // Loop through all percentage changes and add them to the total. - for (String str : Main.getInstance().getCache().getPercentageChanges().keySet()) { - inflationTotal += Main.getInstance().getCache().getPercentageChanges().get(str); - i++; - } - - inflation = (inflationTotal / i); - - } - -} diff --git a/src/main/java/unprotesting/com/github/data/ephemeral/data/ItemData.java b/src/main/java/unprotesting/com/github/data/ephemeral/data/ItemData.java deleted file mode 100644 index 74bcde7..0000000 --- a/src/main/java/unprotesting/com/github/data/ephemeral/data/ItemData.java +++ /dev/null @@ -1,43 +0,0 @@ -package unprotesting.com.github.data.ephemeral.data; - -import lombok.Getter; -import lombok.Setter; - -@Getter -public class ItemData { - - - private int buys; - private int sells; - @Setter - private double price; - - /** - * Initializes the item data. - * @param price The price of the item. - */ - public ItemData(double price) { - - this.buys = 0; - this.sells = 0; - this.price = price; - - } - - /** - * Increases the buy amount. - * @param amount The amount to increase by. - */ - public void increaseBuys(int amount) { - buys = buys + amount; - } - - /** - * Increases the sell amount. - * @param amount The amount to increase by. - */ - public void increaseSells(int amount) { - sells = sells + amount; - } - -} diff --git a/src/main/java/unprotesting/com/github/data/ephemeral/data/LoanData.java b/src/main/java/unprotesting/com/github/data/ephemeral/data/LoanData.java deleted file mode 100644 index 7a068a1..0000000 --- a/src/main/java/unprotesting/com/github/data/ephemeral/data/LoanData.java +++ /dev/null @@ -1,107 +0,0 @@ -package unprotesting.com.github.data.ephemeral.data; - -import java.text.DecimalFormat; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.UUID; - -import lombok.Getter; -import lombok.Setter; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.OfflinePlayer; -import org.bukkit.entity.Player; - -import unprotesting.com.github.Main; -import unprotesting.com.github.config.Config; -import unprotesting.com.github.data.util.LocalDateTimeArrayUtilizer; -import unprotesting.com.github.economy.EconomyFunctions; - -@Getter -@Setter -public class LoanData extends LocalDateTimeArrayUtilizer implements Comparable { - - - private LocalDateTime date; - private Double value; - private Double interestRate; - private Double baseValue; - private String player; - - /** - * Initializes the loan data. - * @param value The value of the loan. - * @param interestRate The interest rate of the loan. - * @param uuid The UUID of the player. - */ - public LoanData(Double value, double interestRate, String uuid) { - this.date = LocalDateTime.now(); - this.interestRate = interestRate; - this.value = value; - this.player = uuid; - this.baseValue = value; - } - - /** - * Initializes the loan data using previous persisted data. - * @param value The value of the loan. - * @param interestRate The interest rate of the loan. - * @param uuid The UUID of the player. - * @param time The time array of the loan. - */ - public LoanData(Double value, double interestRate, String uuid, int[] time) { - this.date = arrayToDate(time); - this.interestRate = interestRate; - this.value = value; - this.player = uuid; - this.baseValue = value; - } - - /** - * Compares the loan data. - */ - @Override - public int compareTo(LoanData o) { - return o.getDate().compareTo(getDate()); - } - - /** - * Payback the loan. - * @return Whether the loan was payed back. - */ - public boolean payBackLoan() { - - DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - OfflinePlayer offPlayer = Bukkit.getPlayer(UUID.fromString(player)); - double balance = EconomyFunctions.getEconomy().getBalance(offPlayer); - - if (balance < getValue()) { - return false; - } - - EconomyFunctions.getEconomy().withdrawPlayer(offPlayer, value); - - if (offPlayer.isOnline()) { - - Player onlinePlayer = (Player) offPlayer; - onlinePlayer.getOpenInventory().close(); - - onlinePlayer.sendMessage(ChatColor.GREEN + "Loan created on " - + date.format(formatter) + " has been paid back."); - - onlinePlayer.sendMessage(ChatColor.GREEN + Config.getConfig().getCurrencySymbol() - + new DecimalFormat(Config.getConfig().getNumberFormat()).format(value) - + " has been withdrawn from your balance."); - - } - - Main.getInstance().getCache().getLoans().remove(this); - Main.getInstance().getCache().getNewLoans().remove(this); - Main.getInstance().getCache().getGdpData().increaseLoss(value - baseValue); - return true; - - } - -} diff --git a/src/main/java/unprotesting/com/github/data/ephemeral/data/MaxBuySellData.java b/src/main/java/unprotesting/com/github/data/ephemeral/data/MaxBuySellData.java deleted file mode 100644 index 1c35bae..0000000 --- a/src/main/java/unprotesting/com/github/data/ephemeral/data/MaxBuySellData.java +++ /dev/null @@ -1,23 +0,0 @@ -package unprotesting.com.github.data.ephemeral.data; - -import lombok.Getter; - -@Getter -public class MaxBuySellData { - - private int buys; - private int sells; - - /** - * Initializes the max buy sell data. - * @param buys The amount of buys. - * @param sells The amount of sells. - */ - public MaxBuySellData(int buys, int sells) { - - this.buys = buys; - this.sells = sells; - - } - -} diff --git a/src/main/java/unprotesting/com/github/data/ephemeral/data/TransactionData.java b/src/main/java/unprotesting/com/github/data/ephemeral/data/TransactionData.java deleted file mode 100644 index 17d101e..0000000 --- a/src/main/java/unprotesting/com/github/data/ephemeral/data/TransactionData.java +++ /dev/null @@ -1,76 +0,0 @@ -package unprotesting.com.github.data.ephemeral.data; - -import java.time.LocalDateTime; - -import lombok.Getter; -import lombok.NonNull; -import unprotesting.com.github.data.ephemeral.other.Sale.SalePositionType; -import unprotesting.com.github.data.util.LocalDateTimeArrayUtilizer; - -// Transaction class for storing general transaction data - -public class TransactionData extends LocalDateTimeArrayUtilizer - implements Comparable { - - @Getter - private LocalDateTime date; - @Getter - private String item; - @Getter - private String player; - @Getter - private int amount; - @Getter - private double price; - @Getter - private SalePositionType position; - - /** - * Initializes the transaction data. - * @param uuid The UUID of the player. - * @param item The item name. - * @param amount The amount of the item. - * @param price The price of the item. - * @param position The TransactionPositionType of the transaction. - */ - public TransactionData(@NonNull String uuid, String item, int amount, - double price, SalePositionType position) { - - this.date = LocalDateTime.now(); - this.player = uuid; - this.item = item; - this.amount = amount; - this.price = price; - this.position = position; - } - - /** - * Initializes the transaction data using previous persisted data. - * @param uuid The UUID of the player. - * @param item The item name. - * @param amount The amount of the item. - * @param price The price of the item. - * @param position The TransactionPositionType of the transaction. - * @param date The time array of the transaction. - */ - public TransactionData(@NonNull String uuid, String item, int amount, - double price, SalePositionType position, int[] date) { - - this.date = arrayToDate(date); - this.player = uuid; - this.item = item; - this.amount = amount; - this.price = price; - this.position = position; - - } - - /** - * Compares the transaction data. - */ - @Override - public int compareTo(TransactionData o) { - return o.getDate().compareTo(getDate()); - } - -} diff --git a/src/main/java/unprotesting/com/github/data/ephemeral/other/PlayerSaleData.java b/src/main/java/unprotesting/com/github/data/ephemeral/other/PlayerSaleData.java deleted file mode 100644 index f2a657d..0000000 --- a/src/main/java/unprotesting/com/github/data/ephemeral/other/PlayerSaleData.java +++ /dev/null @@ -1,101 +0,0 @@ -package unprotesting.com.github.data.ephemeral.other; - -import java.util.ArrayList; -import java.util.List; - -import lombok.Getter; -import unprotesting.com.github.data.ephemeral.other.Sale.SalePositionType; - -@Getter -public class PlayerSaleData { - - private List buys; - private List sells; - private List buysE; - private List sellsE; - - /** - * Initializes the player sale data. - */ - public PlayerSaleData() { - - this.buys = new ArrayList(); - this.sells = new ArrayList(); - this.buysE = new ArrayList(); - this.sellsE = new ArrayList(); - - } - - /** - * Add a new sale to one of the sale lists. - * @param item The item name. - * @param amount The amount of the item. - * @param position The position of the sale. - */ - public void addSale(String item, int amount, SalePositionType position) { - - Sale sale = checkIfSaleExists(item, position); - sale.setAmount(sale.getAmount() + amount); - - switch (position) { - case BUY: - buys.add(sale); - break; - case SELL: - sells.add(sale); - break; - case EBUY: - buysE.add(sale); - break; - case ESELL: - sellsE.add(sale); - break; - default: - break; - } - - } - - // Ensure a sale object for an item doesn't already exist in a select list - private Sale checkIfSaleExists(String item, SalePositionType position) { - - switch (position) { - case BUY: - Sale sale = getSale(item, buys); - buys.remove(sale); - return sale; - case SELL: - Sale sale2 = getSale(item, sells); - sells.remove(sale2); - return sale2; - case EBUY: - Sale sale3 = getSale(item, buysE); - buysE.remove(sale3); - return sale3; - case ESELL: - Sale sale4 = getSale(item, sellsE); - sellsE.remove(sale4); - return sale4; - default: - return new Sale(item, 0); - } - - } - - private Sale getSale(String item, List sales) { - - // Loop through sales and return the sale if it exists. - for (Sale sale : sales) { - - // If the sale exists, return it. - if (sale.getItem().equals(item)) { - return sale; - } - - } - - return new Sale(item, 0); - - } - -} diff --git a/src/main/java/unprotesting/com/github/data/ephemeral/other/Sale.java b/src/main/java/unprotesting/com/github/data/ephemeral/other/Sale.java deleted file mode 100644 index 23d2976..0000000 --- a/src/main/java/unprotesting/com/github/data/ephemeral/other/Sale.java +++ /dev/null @@ -1,27 +0,0 @@ -package unprotesting.com.github.data.ephemeral.other; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class Sale { - - private final String item; - private int amount; - - /** - * Initializes the sale. - */ - public Sale(String item, int amount) { - - this.item = item; - this.amount = amount; - - } - - public enum SalePositionType { - BUY, SELL, EBUY, ESELL - } - -} diff --git a/src/main/java/unprotesting/com/github/data/persistent/Database.java b/src/main/java/unprotesting/com/github/data/persistent/Database.java deleted file mode 100644 index 5418cfa..0000000 --- a/src/main/java/unprotesting/com/github/data/persistent/Database.java +++ /dev/null @@ -1,129 +0,0 @@ -package unprotesting.com.github.data.persistent; - -import lombok.Getter; - -import org.mapdb.DB; -import org.mapdb.DBMaker; -import org.mapdb.DBMaker.Maker; - -import org.mapdb.HTreeMap; -import org.mapdb.Serializer; - -import unprotesting.com.github.Main; -import unprotesting.com.github.config.Config; -import unprotesting.com.github.data.persistent.timeperiods.EconomyInfoTimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.EnchantmentsTimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.GdpTimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.ItemTimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.LoanTimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.TransactionsTimePeriod; - -@Getter -public class Database { - - private DB db; - private HTreeMap map; - - /** - * Initializes the database. - */ - @SuppressWarnings("unchecked") - public Database() { - - createDB(Config.getConfig().getDataLocation()); - this.map = db.hashMap("map", Serializer.INTEGER, Serializer.JAVA).createOrOpen(); - - } - - /** - * Initializes the database in the specified location. - * @param location The location of the database. - */ - @SuppressWarnings("unchecked") - public Database(String location) { - - createDB(location); - this.map = db.hashMap("map", Serializer.INTEGER, Serializer.JAVA).createOrOpen(); - - } - - // Method to build and create or link database to file - /** - * Build and create or link database to file. - * @param location The location of the database. - */ - private void createDB(String location) { - - Maker maker = DBMaker.fileDB(location + "data.db"); - - db = maker.checksumHeaderBypass() - .fileMmapEnableIfSupported() - .fileMmapPreclearDisable() - .cleanerHackEnable() - .allocateStartSize(10 * 1024 * 1024) // 25MB - .allocateIncrement(5 * 1024 * 1024) // 5MB - .closeOnJvmShutdown().make(); - - db.getStore().fileLoad(); - - } - - /** - * Save the cache to the database. - */ - public void saveCacheToLastTP() { - - int size = map.size() - 1; - - if (size < 0) { - return; - } - - TimePeriod tp = map.get(size); - ItemTimePeriod itemTP = tp.getItemTP(); - String[] items = itemTP.getItems(); - int[] buys = itemTP.getBuys(); - int[] sells = itemTP.getSells(); - int pos = 0; - - // Loop through all items and save the buy and sell values. - for (String item : items) { - buys[pos] = buys[pos] + Main.getInstance().getCache().getItems().get(item).getBuys(); - sells[pos] = sells[pos] + Main.getInstance().getCache().getItems().get(item).getSells(); - itemTP.setBuys(buys); - itemTP.setSells(sells); - pos++; - } - - EnchantmentsTimePeriod enchantmentsTP = tp.getEnchantmentsTP(); - String[] enchantments = enchantmentsTP.getItems(); - int[] enchantmentBuys = enchantmentsTP.getBuys(); - int[] enchantmentSells = enchantmentsTP.getSells(); - pos = 0; - - // Loop through all enchantments and save the buy and sell values. - for (String enchantment : enchantments) { - - enchantmentBuys[pos] = enchantmentBuys[pos] - + Main.getInstance().getCache().getEnchantments().get(enchantment).getBuys(); - - enchantmentSells[pos] = enchantmentSells[pos] - + Main.getInstance().getCache().getEnchantments().get(enchantment).getSells(); - - enchantmentsTP.setBuys(enchantmentBuys); - enchantmentsTP.setSells(enchantmentSells); - pos++; - - } - - tp.setItemTP(itemTP); - tp.setEnchantmentsTP(enchantmentsTP); - tp.setGdpTP(new GdpTimePeriod()); - tp.setLoanTP(new LoanTimePeriod()); - tp.setTransactionsTP(new TransactionsTimePeriod()); - tp.setEconomyInfoTP(new EconomyInfoTimePeriod()); - map.put(map.size() - 1, tp); - - } - -} diff --git a/src/main/java/unprotesting/com/github/data/persistent/TimePeriod.java b/src/main/java/unprotesting/com/github/data/persistent/TimePeriod.java deleted file mode 100644 index 74bd430..0000000 --- a/src/main/java/unprotesting/com/github/data/persistent/TimePeriod.java +++ /dev/null @@ -1,72 +0,0 @@ -package unprotesting.com.github.data.persistent; - -import java.io.Serializable; - -import lombok.Getter; -import lombok.Setter; -import unprotesting.com.github.Main; -import unprotesting.com.github.data.persistent.timeperiods.EconomyInfoTimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.EnchantmentsTimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.GdpTimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.ItemTimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.LoanTimePeriod; -import unprotesting.com.github.data.persistent.timeperiods.TransactionsTimePeriod; - -@Getter -@Setter -public class TimePeriod implements Serializable { - - private static final long serialVersionUID = -1102531403L; - - private ItemTimePeriod itemTP; - private EnchantmentsTimePeriod enchantmentsTP; - private TransactionsTimePeriod transactionsTP; - private LoanTimePeriod loanTP; - private GdpTimePeriod gdpTP; - private EconomyInfoTimePeriod economyInfoTP; - - /** - * Initializes the time periods. - */ - public TimePeriod() { - getFromCache(); - } - - /** - * Initializes the time periods. - * @param empty Whether the time periods are empty or not. - */ - public TimePeriod(boolean empty) { - - if (!empty) { - getFromCache(); - } - - } - - /** - * Adds the time periods to the database. - */ - public void addToMap() { - - int size = Main.getInstance().getDatabase().getMap().size(); - Main.getInstance().getDatabase().getMap().put(size, this); - - } - - /** - * Initializes the time periods. - */ - private void getFromCache() { - - itemTP = new ItemTimePeriod(); - enchantmentsTP = new EnchantmentsTimePeriod(); - transactionsTP = new TransactionsTimePeriod(); - loanTP = new LoanTimePeriod(); - gdpTP = new GdpTimePeriod(); - economyInfoTP = new EconomyInfoTimePeriod(); - - } - - -} diff --git a/src/main/java/unprotesting/com/github/data/persistent/timeperiods/EconomyInfoTimePeriod.java b/src/main/java/unprotesting/com/github/data/persistent/timeperiods/EconomyInfoTimePeriod.java deleted file mode 100644 index 21d14ae..0000000 --- a/src/main/java/unprotesting/com/github/data/persistent/timeperiods/EconomyInfoTimePeriod.java +++ /dev/null @@ -1,25 +0,0 @@ -package unprotesting.com.github.data.persistent.timeperiods; - -import java.io.Serializable; - -import lombok.Getter; -import unprotesting.com.github.Main; - -@Getter -public class EconomyInfoTimePeriod implements Serializable { - - private static final long serialVersionUID = -1102531404L; - - private double sellPriceDifference; - - /** - * Initializes the economy info time period. - */ - public EconomyInfoTimePeriod() { - - this.sellPriceDifference = Main.getInstance().getCache() - .getEconomyInfo().getSellPriceDifference(); - - } - -} diff --git a/src/main/java/unprotesting/com/github/data/persistent/timeperiods/EnchantmentsTimePeriod.java b/src/main/java/unprotesting/com/github/data/persistent/timeperiods/EnchantmentsTimePeriod.java deleted file mode 100644 index 3f003e5..0000000 --- a/src/main/java/unprotesting/com/github/data/persistent/timeperiods/EnchantmentsTimePeriod.java +++ /dev/null @@ -1,66 +0,0 @@ -package unprotesting.com.github.data.persistent.timeperiods; - -import java.io.Serializable; -import java.util.Set; - -import lombok.Getter; -import lombok.Setter; -import unprotesting.com.github.Main; -import unprotesting.com.github.data.ephemeral.LocalDataCache; -import unprotesting.com.github.data.ephemeral.data.EnchantmentData; -import unprotesting.com.github.data.util.BuyableTimePeriodFunctions; - -// Enchantment time period object for storing enchantment price, ratio and buy/sell data - -@Getter -public class EnchantmentsTimePeriod extends BuyableTimePeriodFunctions implements Serializable { - - private static final long serialVersionUID = -1102531405L; - - @Setter - private int[] buys; - @Setter - private int[] sells; - private double[] prices; - private double[] ratios; - private String[] items; - - /** - * Initializes the enchantment time period. - */ - public EnchantmentsTimePeriod() { - Set set = Main.getInstance().getCache().getEnchantments().keySet(); - int size = set.size(); - init(size); - this.ratios = new double[size]; - this.prices = new double[size]; - this.buys = new int[size]; - this.sells = new int[size]; - this.items = new String[size]; - int i = 0; - LocalDataCache cache = Main.getInstance().getCache(); - - for (String key : set) { - EnchantmentData data = cache.getEnchantments().get(key); - this.items[i] = key; - setVars(i, data); - i++; - } - - } - - /** - * Set the variables for the time period. - * @param pos The index of the time period. - * @param data The enchantment data. - */ - private void setVars(int pos, EnchantmentData data) { - - buys[pos] = data.getBuys(); - sells[pos] = data.getSells(); - prices[pos] = data.getPrice(); - ratios[pos] = data.getRatio(); - - } - -} diff --git a/src/main/java/unprotesting/com/github/data/persistent/timeperiods/GdpTimePeriod.java b/src/main/java/unprotesting/com/github/data/persistent/timeperiods/GdpTimePeriod.java deleted file mode 100644 index 00d2483..0000000 --- a/src/main/java/unprotesting/com/github/data/persistent/timeperiods/GdpTimePeriod.java +++ /dev/null @@ -1,39 +0,0 @@ -package unprotesting.com.github.data.persistent.timeperiods; - -import java.io.Serializable; - -import lombok.Getter; -import unprotesting.com.github.Main; -import unprotesting.com.github.data.ephemeral.data.GdpData; - -@Getter -public class GdpTimePeriod implements Serializable { - - private static final long serialVersionUID = -1102531406L; - - private double gdp; - private double balance; - private double debt; - private double loss; - private double inflation; - private int playerCount; - - /** - * Initializes the GDP time period. - */ - public GdpTimePeriod() { - - Main.getInstance().getCache().getGdpData().updateDebt(); - Main.getInstance().getCache().getGdpData().updateBalance(); - Main.getInstance().getCache().getGdpData().updateInflation(); - GdpData data = Main.getInstance().getCache().getGdpData(); - this.gdp = data.getGdp(); - this.balance = data.getBalance(); - this.playerCount = data.getPlayerCount(); - this.debt = data.getDebt(); - this.loss = data.getLoss(); - this.inflation = data.getInflation(); - - } - -} diff --git a/src/main/java/unprotesting/com/github/data/persistent/timeperiods/ItemTimePeriod.java b/src/main/java/unprotesting/com/github/data/persistent/timeperiods/ItemTimePeriod.java deleted file mode 100644 index 4074abd..0000000 --- a/src/main/java/unprotesting/com/github/data/persistent/timeperiods/ItemTimePeriod.java +++ /dev/null @@ -1,62 +0,0 @@ -package unprotesting.com.github.data.persistent.timeperiods; - -import java.io.Serializable; -import java.util.Set; - -import lombok.Getter; -import lombok.Setter; -import unprotesting.com.github.Main; -import unprotesting.com.github.data.ephemeral.LocalDataCache; -import unprotesting.com.github.data.ephemeral.data.ItemData; -import unprotesting.com.github.data.util.BuyableTimePeriodFunctions; - -@Getter -public class ItemTimePeriod extends BuyableTimePeriodFunctions implements Serializable { - - private static final long serialVersionUID = -1102531407L; - - @Setter - private int[] buys; - @Setter - private int[] sells; - private double[] prices; - private String[] items; - - /** - * Initializes the item time period. - */ - public ItemTimePeriod() { - - Set set = Main.getInstance().getCache().getItems().keySet(); - int size = set.size(); - init(size); - this.buys = new int[size]; - this.sells = new int[size]; - this.prices = new double[size]; - this.items = new String[size]; - int i = 0; - LocalDataCache cache = Main.getInstance().getCache(); - - for (String key : set) { - - ItemData data = cache.getItems().get(key); - this.items[i] = key; - setVars(i, data); - i++; - - } - - } - - /** - * Set the variables for the time period. - * @param pos The index of the time period. - * @param data The item data. - */ - private void setVars(int pos, ItemData data) { - buys[pos] = data.getBuys(); - sells[pos] = data.getSells(); - prices[pos] = data.getPrice(); - } - -} diff --git a/src/main/java/unprotesting/com/github/data/persistent/timeperiods/LoanTimePeriod.java b/src/main/java/unprotesting/com/github/data/persistent/timeperiods/LoanTimePeriod.java deleted file mode 100644 index a16a637..0000000 --- a/src/main/java/unprotesting/com/github/data/persistent/timeperiods/LoanTimePeriod.java +++ /dev/null @@ -1,65 +0,0 @@ -package unprotesting.com.github.data.persistent.timeperiods; - -import java.io.Serializable; - -import lombok.Getter; -import unprotesting.com.github.Main; -import unprotesting.com.github.data.ephemeral.data.LoanData; -import unprotesting.com.github.data.util.LocalDateTimeArrayUtilizer; - -@Getter -public class LoanTimePeriod extends LocalDateTimeArrayUtilizer implements Serializable { - - private static final long serialVersionUID = -1102531408L; - - private double[] values; - private double[] interestRates; - private double[] baseValues; - private String[] players; - private int[][] time; - - /** - * Initializes the loan time period. - */ - public LoanTimePeriod() { - - init(Main.getInstance().getCache().getNewLoans().size()); - int i = 0; - - for (LoanData data : Main.getInstance().getCache().getNewLoans()) { - - setVars(i, data); - i++; - - } - - } - - /** - * Set the variables for the time period. - * @param pos The index of the time period. - * @param data The loan data. - */ - private void setVars(int pos, LoanData data) { - - values[pos] = data.getValue(); - interestRates[pos] = data.getInterestRate(); - players[pos] = data.getPlayer(); - time[pos] = dateToIntArray(data.getDate()); - values[pos] = data.getBaseValue(); - - } - - /** - * Initializes the time period. - * @param size The size of the time period. - */ - private void init(int size) { - values = new double[size]; - interestRates = new double[size]; - players = new String[size]; - time = new int[size][6]; - baseValues = new double[size]; - } - -} diff --git a/src/main/java/unprotesting/com/github/data/persistent/timeperiods/TransactionsTimePeriod.java b/src/main/java/unprotesting/com/github/data/persistent/timeperiods/TransactionsTimePeriod.java deleted file mode 100644 index 749ac3e..0000000 --- a/src/main/java/unprotesting/com/github/data/persistent/timeperiods/TransactionsTimePeriod.java +++ /dev/null @@ -1,72 +0,0 @@ -package unprotesting.com.github.data.persistent.timeperiods; - -import java.io.Serializable; - -import lombok.Getter; -import unprotesting.com.github.Main; -import unprotesting.com.github.data.ephemeral.data.TransactionData; -import unprotesting.com.github.data.util.LocalDateTimeArrayUtilizer; - -@Getter -public class TransactionsTimePeriod extends LocalDateTimeArrayUtilizer implements Serializable { - - private static final long serialVersionUID = -1102531409L; - - private double[] prices; - private int[] amounts; - private int[][] time; - private String[] players; - private String[] items; - private String[] positions; - - /** - * Initializes the transaction time period. - */ - public TransactionsTimePeriod() { - - init(Main.getInstance().getCache().getNewTransactions().size()); - int i = 0; - - // Add all transactions in cache to the time period. - for (TransactionData data : Main.getInstance().getCache().getNewTransactions()) { - - setVars(i, data); - i++; - - } - - } - - /** - * Set the variables for the time period. - * @param pos The index of the time period. - * @param data The transaction data. - */ - private void setVars(int pos, TransactionData data) { - - prices[pos] = data.getPrice(); - amounts[pos] = data.getAmount(); - players[pos] = data.getPlayer(); - items[pos] = data.getItem(); - time[pos] = dateToIntArray(data.getDate()); - positions[pos] = data.getPosition().toString(); - - // If the player is null throw an exception. - if (players[pos] == null) { - throw new NullPointerException("Transaction player can't be null in database"); - } - - } - - private void init(int size) { - - prices = new double[size]; - players = new String[size]; - items = new String[size]; - time = new int[size][6]; - amounts = new int[size]; - positions = new String[size]; - - } - -} diff --git a/src/main/java/unprotesting/com/github/data/util/BuyableTimePeriodFunctions.java b/src/main/java/unprotesting/com/github/data/util/BuyableTimePeriodFunctions.java deleted file mode 100644 index aa1a467..0000000 --- a/src/main/java/unprotesting/com/github/data/util/BuyableTimePeriodFunctions.java +++ /dev/null @@ -1,27 +0,0 @@ -package unprotesting.com.github.data.util; - -import lombok.Getter; - -public abstract class BuyableTimePeriodFunctions { - - @Getter - private int[] buys; - @Getter - private int[] sells; - @Getter - private double[] prices; - @Getter - private String[] items; - - /** - * Initializes the buyable time period functions. - * @param size The size of the buyable time period. - */ - public void init(int size) { - this.buys = new int[size]; - this.sells = new int[size]; - this.prices = new double[size]; - this.items = new String[size]; - } - -} diff --git a/src/main/java/unprotesting/com/github/data/util/LocalDateTimeArrayUtilizer.java b/src/main/java/unprotesting/com/github/data/util/LocalDateTimeArrayUtilizer.java deleted file mode 100644 index 715b84f..0000000 --- a/src/main/java/unprotesting/com/github/data/util/LocalDateTimeArrayUtilizer.java +++ /dev/null @@ -1,36 +0,0 @@ -package unprotesting.com.github.data.util; - -import java.time.LocalDateTime; - -public abstract class LocalDateTimeArrayUtilizer { - - /** - * Converts a de-serialized LocalDateTime object to a LocalDateTime. - * @param time The de-serialized LocalDateTime object. - * @return The LocalDateTime. - */ - public LocalDateTime arrayToDate(int[] time) { - return LocalDateTime.of(time[5], time[4], time[3], time[2], time[1], time[0], 0); - } - - /** - * Converts a LocalDateTime to a serializable integer array. - * @param date The LocalDateTime. - * @return The serializable integer array. - */ - public int[] dateToIntArray(LocalDateTime date) { - - return new int[]{ - - date.getSecond(), - date.getMinute(), - date.getHour(), - date.getDayOfMonth(), - date.getMonthValue(), - date.getYear() - - }; - - } - -} diff --git a/src/main/java/unprotesting/com/github/events/AutoTuneInventoryCheckEvent.java b/src/main/java/unprotesting/com/github/events/AutoTuneInventoryCheckEvent.java new file mode 100644 index 0000000..92803d4 --- /dev/null +++ b/src/main/java/unprotesting/com/github/events/AutoTuneInventoryCheckEvent.java @@ -0,0 +1,105 @@ +package unprotesting.com.github.events; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.UUID; + +import lombok.Getter; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +import unprotesting.com.github.config.Config; +import unprotesting.com.github.data.CollectFirst; +import unprotesting.com.github.data.CollectFirst.CollectFirstSetting; +import unprotesting.com.github.data.Shop; +import unprotesting.com.github.data.ShopUtil; + + +public class AutoTuneInventoryCheckEvent extends Event { + + @Getter + private final HandlerList handlers = new HandlerList(); + + private static List shopNames; + + /** + * Checks all online players inventories for autosell items + * and to update collect first settings. + * @param isAsync Whether to run this in an async task. + */ + public AutoTuneInventoryCheckEvent(boolean isAsync) { + super(isAsync); + shopNames = Arrays.asList(ShopUtil.getShopNames()); + for (Player player : Bukkit.getOnlinePlayers()) { + checkInventory(player); + } + } + + private void checkInventory(Player player) { + UUID uuid = player.getUniqueId(); + for (ItemStack item : player.getInventory().getContents()) { + + if (!checkIfValidShop(item)) { + continue; + } + String name = item.getType().toString().toLowerCase(); + Shop shop = ShopUtil.getShop(name); + boolean autosellEnabled = Config.get().getAutosell().getBoolean(uuid + "." + name, false); + boolean update = false; + if (item.getEnchantments().size() > 0) { + autosellEnabled = false; + } + + if (autosellEnabled) { + if (ShopUtil.getSellsLeft(player, name) - item.getAmount() < 0) { + continue; + } + HashMap map = player.getInventory().removeItemAnySlot(item); + int amount = item.getAmount(); + if (!map.isEmpty()) { + amount = amount - map.get(0).getAmount(); + } + shop.addAutosell(uuid, amount); + shop.addSells(uuid, amount); + update = true; + } + + CollectFirst cf = shop.getSetting(); + if (cf.getSetting().equals(CollectFirstSetting.SERVER)) { + if (!cf.isFoundInServer()) { + cf.setFoundInServer(true); + shop.setSetting(cf); + update = true; + } + } else if (cf.getSetting().equals(CollectFirstSetting.PLAYER)) { + cf.addPlayer(uuid); + shop.setSetting(cf); + update = true; + } + + if (update) { + ShopUtil.putShop(name, shop); + } + } + } + + private boolean checkIfValidShop(ItemStack item) { + if (item == null) { + return false; + } + + String name = item.getType().toString().toLowerCase(); + + if (!shopNames.contains(name)) { + return false; + } + + return true; + } + +} diff --git a/src/main/java/unprotesting/com/github/events/AutosellProfitEvent.java b/src/main/java/unprotesting/com/github/events/AutosellProfitEvent.java new file mode 100644 index 0000000..fa7d14d --- /dev/null +++ b/src/main/java/unprotesting/com/github/events/AutosellProfitEvent.java @@ -0,0 +1,83 @@ +package unprotesting.com.github.events; + +import java.util.Map; +import java.util.UUID; + +import lombok.Getter; + +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; + +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import unprotesting.com.github.config.Config; +import unprotesting.com.github.data.EconomyDataUtil; +import unprotesting.com.github.data.Shop; +import unprotesting.com.github.data.ShopUtil; +import unprotesting.com.github.data.Transaction; +import unprotesting.com.github.data.Transaction.TransactionType; +import unprotesting.com.github.util.EconomyUtil; +import unprotesting.com.github.util.Format; + +public class AutosellProfitEvent extends Event { + + @Getter + private final HandlerList handlers = new HandlerList(); + + /** + * Updates the autosell profit. + * @param isAsync Whether the event is being run async or not. + */ + public AutosellProfitEvent(boolean isAsync) { + super(isAsync); + deposit(); + } + + private void deposit() { + for (String s : ShopUtil.getShopNames()) { + + Shop shop = ShopUtil.getShop(s); + Map autosell = shop.getAutosell(); + + if (autosell.isEmpty()) { + continue; + } + + for (Map.Entry entry : autosell.entrySet()) { + + if (entry.getValue() <= 0) { + continue; + } + + int amount = entry.getValue(); + double price = shop.getSellPrice(); + double total = price * amount; + OfflinePlayer player = Bukkit.getOfflinePlayer(entry.getKey()); + EconomyUtil.getEconomy().depositPlayer(player, entry.getValue()); + ShopUtil.addTransaction(new Transaction( + price, amount, entry.getKey(), s, TransactionType.SELL)); + EconomyDataUtil.increaseEconomyData("GDP", total / 2); + double loss = shop.getPrice() * amount - total; + EconomyDataUtil.increaseEconomyData("LOSS", loss); + String balance = Format.currency(EconomyUtil.getEconomy().getBalance(player)); + + TagResolver resolver = TagResolver.resolver( + Placeholder.parsed("total", Format.currency(total)), + Placeholder.parsed("balance", balance)); + + + if (player.isOnline()) { + Format.sendMessage(player.getPlayer(), Config.get().getAutosellProfit(), resolver); + } + + } + + shop.clearAutosell(); + ShopUtil.putShop(s, shop); + } + } + +} diff --git a/src/main/java/unprotesting/com/github/events/IpCheckEvent.java b/src/main/java/unprotesting/com/github/events/IpCheckEvent.java new file mode 100644 index 0000000..e2f1a6e --- /dev/null +++ b/src/main/java/unprotesting/com/github/events/IpCheckEvent.java @@ -0,0 +1,53 @@ +package unprotesting.com.github.events; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.URL; + +import lombok.Getter; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import unprotesting.com.github.config.Config; +import unprotesting.com.github.util.Format; + +public class IpCheckEvent extends Event { + + @Getter + private static String ip; + + @Getter + private final HandlerList handlers = new HandlerList(); + + /** + * Get the IP of the server from http://checkip.amazonaws.com. + * @param isAsync Whether to run the check in a separate thread. + */ + public IpCheckEvent(boolean isAsync) { + super(isAsync); + + try { + getIpString(); + } catch (IOException e) { + Format.getLog().severe("Could not get IP!"); + Format.getLog().config(e.toString()); + ip = "http://autotune.xyz"; + } + + } + + private void getIpString() throws MalformedURLException, IOException { + + URL whatIsmMyIp = new URL("http://checkip.amazonaws.com"); + BufferedReader in = new BufferedReader(new InputStreamReader(whatIsmMyIp.openStream())); + String hostIP = in.readLine(); + ip = "http://" + hostIP + ":" + Config.get().getPort() + "/trade.html"; + + } + + + +} diff --git a/src/main/java/unprotesting/com/github/events/LoanInterestEvent.java b/src/main/java/unprotesting/com/github/events/LoanInterestEvent.java new file mode 100644 index 0000000..f140b0a --- /dev/null +++ b/src/main/java/unprotesting/com/github/events/LoanInterestEvent.java @@ -0,0 +1,38 @@ +package unprotesting.com.github.events; + +import java.util.Map; + +import lombok.Getter; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import unprotesting.com.github.data.Database; +import unprotesting.com.github.data.Loan; + +public class LoanInterestEvent extends Event { + + @Getter + private final HandlerList handlers = new HandlerList(); + + /** + * Updates the loan data. + * @param isAsync Whether the event is being run async or not. + */ + public LoanInterestEvent(boolean isAsync) { + super(isAsync); + updateLoans(); + } + + /** + * Updates the loan data. + */ + public void updateLoans() { + for (Map.Entry entry : Database.get().getLoans().entrySet()) { + Loan loan = entry.getValue(); + loan.update(); + Database.get().updateLoan(entry.getKey(), loan); + } + } + +} diff --git a/src/main/java/unprotesting/com/github/events/TimePeriodEvent.java b/src/main/java/unprotesting/com/github/events/TimePeriodEvent.java new file mode 100644 index 0000000..0afa38c --- /dev/null +++ b/src/main/java/unprotesting/com/github/events/TimePeriodEvent.java @@ -0,0 +1,59 @@ +package unprotesting.com.github.events; + +import lombok.Getter; + +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import unprotesting.com.github.config.Config; +import unprotesting.com.github.data.Database; +import unprotesting.com.github.data.Shop; +import unprotesting.com.github.data.ShopUtil; +import unprotesting.com.github.util.Format; +import unprotesting.com.github.util.UtilFunctions; + +public class TimePeriodEvent extends Event { + + @Getter + private final HandlerList handlers = new HandlerList(); + + /** + * Constructor for the TimePeriodEvent class. + * @param isAsync Whether to run the check in a separate thread. + */ + public TimePeriodEvent(boolean isAsync) { + super(isAsync); + int players = UtilFunctions.calculatePlayerCount(); + + if (players < Config.get().getMinimumPlayers()) { + Format.getLog().config("Not enough players to start price update. (" + + players + " < " + Config.get().getMinimumPlayers() + ")"); + return; + } + + Format.getLog().config("Price update started as there are " + players + " players online."); + updatePrices(); + Database.get().updateChanges(); + Database.get().updateRelations(); + } + + private void updatePrices() { + + for (String s : ShopUtil.getShopNames()) { + Shop shop = ShopUtil.getShop(s); + double initialPrice = shop.getPrice(); + double strength = shop.strength(); + double newPrice = initialPrice + initialPrice * strength * shop.getVolatility() * 0.01; + shop.timePeriod(newPrice); + ShopUtil.putShop(s, shop); + + if (newPrice != initialPrice) { + Format.getLog().config("Price of " + s + " changed from " + + Format.currency(initialPrice) + " to " + Format.currency(newPrice)); + Format.getLog().finer("Changed by " + Format.currency(newPrice - initialPrice)); + Format.getLog().finest("Volatility: " + shop.getVolatility()); + Format.getLog().finest("Strength: " + strength); + } + } + } +} diff --git a/src/main/java/unprotesting/com/github/events/TutorialEvent.java b/src/main/java/unprotesting/com/github/events/TutorialEvent.java new file mode 100644 index 0000000..1f2f28a --- /dev/null +++ b/src/main/java/unprotesting/com/github/events/TutorialEvent.java @@ -0,0 +1,44 @@ +package unprotesting.com.github.events; + +import lombok.Getter; + +import net.kyori.adventure.audience.Audience; +import net.kyori.adventure.text.Component; + +import org.bukkit.Bukkit; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import unprotesting.com.github.config.Config; +import unprotesting.com.github.util.Format; + + + +public class TutorialEvent extends Event { + + @Getter + private final HandlerList handlers = new HandlerList(); + + private int position; + + /** + * Sends the tutorial messages to all players. + */ + public TutorialEvent(boolean isAsync) { + super(isAsync); + + if (Config.get().getTutorial().isEmpty() || Bukkit.getOnlinePlayers().size() < 1) { + return; + } + + if (position >= Config.get().getTutorial().size()) { + position = 0; + } + + Component message = Format.getComponent(Config.get().getTutorial().get(position)); + Audience audience = Audience.audience(Bukkit.getOnlinePlayers()); + audience.sendMessage(message); + position++; + } + +} diff --git a/src/main/java/unprotesting/com/github/events/async/AutosellProfitUpdateEvent.java b/src/main/java/unprotesting/com/github/events/async/AutosellProfitUpdateEvent.java deleted file mode 100644 index c3f8c3f..0000000 --- a/src/main/java/unprotesting/com/github/events/async/AutosellProfitUpdateEvent.java +++ /dev/null @@ -1,77 +0,0 @@ -package unprotesting.com.github.events.async; - -import java.text.DecimalFormat; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; - -import lombok.Getter; -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; - -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -import unprotesting.com.github.Main; -import unprotesting.com.github.config.Config; -import unprotesting.com.github.config.Messages; -import unprotesting.com.github.data.ephemeral.data.AutosellData; -import unprotesting.com.github.economy.EconomyFunctions; - -public class AutosellProfitUpdateEvent extends Event { - - @Getter - private final HandlerList handlers = new HandlerList(); - - /** - * Updates the autosell profit. - * @param isAsync Whether the event is being run async or not. - */ - public AutosellProfitUpdateEvent(boolean isAsync) { - - super(isAsync); - depositCachedMoney(); - Main.getInstance().setAutosellData(new AutosellData()); - - } - - /** - * Deposits the cached money. - */ - private void depositCachedMoney() { - - DecimalFormat df = new DecimalFormat(Config.getConfig().getNumberFormat()); - ConcurrentHashMap data = Main.getInstance().getAutosellData().getData(); - - /** - * Loop through the cached money and deposit it for each player. - */ - for (String uuid : data.keySet()) { - - OfflinePlayer offPlayer = Bukkit.getOfflinePlayer(UUID.fromString(uuid)); - - if (data.get(uuid) == null || data.get(uuid) == 0) { - continue; - } - - EconomyFunctions.getEconomy().depositPlayer(offPlayer, data.get(uuid)); - - // If the player is offline then skip the event. - if (!offPlayer.isOnline()) { - continue; - } - - String amount = df.format(data.get(uuid)); - Player player = offPlayer.getPlayer(); - TagResolver resolver = TagResolver.resolver(Placeholder.parsed("total", amount)); - - player.sendMessage(Main.getInstance().getMm().deserialize( - Messages.getMessages().getAutoSellProfitUpdate(), resolver)); - - } - - } - -} \ No newline at end of file diff --git a/src/main/java/unprotesting/com/github/events/async/IpCheckEvent.java b/src/main/java/unprotesting/com/github/events/async/IpCheckEvent.java deleted file mode 100644 index 0f1cb28..0000000 --- a/src/main/java/unprotesting/com/github/events/async/IpCheckEvent.java +++ /dev/null @@ -1,59 +0,0 @@ -package unprotesting.com.github.events.async; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.net.URL; - -import lombok.Getter; - -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -import unprotesting.com.github.Main; -import unprotesting.com.github.config.Config; - -public class IpCheckEvent extends Event { - - @Getter - private final HandlerList handlers = new HandlerList(); - - /** - * Checks the IP of the server. - */ - public IpCheckEvent(boolean isAsync) { - - super(isAsync); - Main.getInstance().setServerIPs(getIP()); - - } - - /** - * Gets the server IPs. - * @return The server IPs. - */ - private String[] getIP() { - - String hostIP; - - try { - - URL whatIsmMyIp = new URL("http://checkip.amazonaws.com"); - BufferedReader in = new BufferedReader(new InputStreamReader(whatIsmMyIp.openStream())); - hostIP = in.readLine().trim(); - - } catch (IOException e) { - - Main.getInstance().getLogger().severe("Could not get the server IPs."); - String error = "http://autotune.xyz"; - return new String[] { error, error }; - - } - - String base = "http://" + hostIP + ":" + Config.getConfig().getPort(); - String[] output = { base + "/trade.html" }; - return output; - - } - -} diff --git a/src/main/java/unprotesting/com/github/events/async/LoanUpdateEvent.java b/src/main/java/unprotesting/com/github/events/async/LoanUpdateEvent.java deleted file mode 100644 index 5114462..0000000 --- a/src/main/java/unprotesting/com/github/events/async/LoanUpdateEvent.java +++ /dev/null @@ -1,61 +0,0 @@ -package unprotesting.com.github.events.async; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import lombok.Getter; - -import org.bukkit.OfflinePlayer; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -import unprotesting.com.github.Main; -import unprotesting.com.github.config.Config; -import unprotesting.com.github.data.ephemeral.data.LoanData; -import unprotesting.com.github.economy.EconomyFunctions; - -public class LoanUpdateEvent extends Event { - - @Getter - private final HandlerList handlers = new HandlerList(); - - /** - * Updates the loan data. - * @param isAsync Whether the event is being run async or not. - */ - public LoanUpdateEvent(boolean isAsync) { - - super(isAsync); - updateLoans(); - - } - - private void updateLoans() { - - List output = new ArrayList<>(); - - // Loop through all loans and update them. - for (LoanData loan : Main.getInstance().getCache().getLoans()) { - - loan.setValue(loan.getValue() + loan.getValue() * 0.01 * loan.getInterestRate()); - - OfflinePlayer offlinePlayer = Main.getInstance().getServer() - .getOfflinePlayer(UUID.fromString(loan.getPlayer())); - - double balance = EconomyFunctions.getEconomy().getBalance(offlinePlayer); - - // If the loan is overpaid then remove it. - if (balance - loan.getValue() < Config.getConfig().getMaxDebt()) { - loan.payBackLoan(); - } - - output.add(loan); - - } - - Main.getInstance().getCache().setLoans(output); - - } - -} diff --git a/src/main/java/unprotesting/com/github/events/async/PriceUpdateEvent.java b/src/main/java/unprotesting/com/github/events/async/PriceUpdateEvent.java deleted file mode 100644 index 7f68dcd..0000000 --- a/src/main/java/unprotesting/com/github/events/async/PriceUpdateEvent.java +++ /dev/null @@ -1,218 +0,0 @@ -package unprotesting.com.github.events.async; - -import java.util.Arrays; - -import lombok.Getter; - -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -import unprotesting.com.github.Main; -import unprotesting.com.github.config.Config; -import unprotesting.com.github.data.ephemeral.data.EnchantmentData; -import unprotesting.com.github.data.ephemeral.data.ItemData; -import unprotesting.com.github.data.persistent.Database; -import unprotesting.com.github.data.persistent.TimePeriod; -import unprotesting.com.github.util.UtilFunctions; - -public class PriceUpdateEvent extends Event { - - @Getter - private final HandlerList handlers = new HandlerList(); - - /** - * Updates the prices. - * @param isAsync Whether the event is being run async or not. - */ - public PriceUpdateEvent(boolean isAsync) { - - super(isAsync); - - calculateAndLoad(); - - } - - /** - * Calculates the prices and loads them into the database. - */ - private void calculateAndLoad() { - - int playerCount = UtilFunctions.calculatePlayerCount(); - - // If the player count is less than "update-prices-threshold" then don't update the prices. - if (playerCount < Config.getConfig().getUpdatePricesThreshold()) { - - Main.getInstance().getLogger().info("Player count is less than " - + Config.getConfig().getUpdatePricesThreshold() - + " so not updating prices."); - - return; - } - - Main.getInstance().getLogger().info("Calculating prices as player count is " + playerCount); - - Main.getInstance().updateTimePeriod(); - updateItems(); - updateEnchantments(); - Main.getInstance().getCache().updatePercentageChanges(); - - } - - /** - * Updates the prices of all items. - */ - private void updateItems() { - - // Loop through all items and update them. - for (String item : Main.getInstance().getCache().getItems().keySet()) { - - // If the item is locked then don't update it. - if (Main.getInstance().getDataFiles().getShops().getConfigurationSection("shops") - .getConfigurationSection(item).getBoolean("locked", false)) { - - continue; - - } - - ItemData data = Main.getInstance().getCache().getItems().get(item); - double initialPrice = data.getPrice(); - double[] sb = loadAverageBuySellValue(item, false); - double[] volatility = getMaxMinVolatility("shops", item); - data.setPrice(UtilFunctions.calculateNewPrice(data.getPrice(), volatility, sb[0], sb[1])); - Main.getInstance().getCache().getItems().put(item, data); - - if (data.getPrice() != initialPrice) { - - Main.getInstance().getLogger().info("Updated price of " - + item + " from " + initialPrice + " to " + data.getPrice()); - - } - - } - - } - - /** - * Updates the prices of all enchantments. - */ - private void updateEnchantments() { - - // Loop through all enchantments and update them. - for (String item : Main.getInstance().getCache().getEnchantments().keySet()) { - - // If the enchantment is locked then don't update it. - if (Main.getInstance().getDataFiles().getEnchantments() - .getConfigurationSection("enchantments." + item).getBoolean("locked", false)) { - - continue; - - } - - EnchantmentData data = Main.getInstance().getCache().getEnchantments().get(item); - double[] sb = loadAverageBuySellValue(item, true); - double[] volatility = getMaxMinVolatility("enchantments", item); - data.setPrice(UtilFunctions.calculateNewPrice(data.getPrice(), volatility, sb[0], sb[1])); - data.setRatio(UtilFunctions.calculateNewPrice(data.getRatio(), volatility, sb[0], sb[1])); - Main.getInstance().getCache().getEnchantments().put(item, data); - - } - - } - - - - /** - * Loads the average buy and sell values for an item. - * @param item The item. - * @param isEnchantment Whether the item is an enchantment or not. - * @return The average buy and sell values. - */ - private double[] loadAverageBuySellValue(String item, boolean isEnchantment) { - - Database db = Main.getInstance().getDatabase(); - int size = Main.getInstance().getDatabase().getMap().size(); - int y = 1; - double finalBuys = 0; - double finalSells = 0; - - // Loop through all time periods and calculate the average buy and sell values. - for (int i = 0; i < size; i++) { - - y = (int) Math.round(Config.getConfig().getDataSelectionM() - * Math.pow(i, Config.getConfig().getDataSelectionZ()) - + Config.getConfig().getDataSelectionC()); - - TimePeriod period = db.getMap().get(size - y); - double buys = 0; - double sells = 0; - - try { - - // If the item is an enchantment then load the enchantment data - // otherwise load the item data. - if (isEnchantment) { - - int loc = Arrays.asList(period.getEnchantmentsTP().getItems()).indexOf(item); - buys = period.getEnchantmentsTP().getBuys()[loc]; - sells = period.getEnchantmentsTP().getSells()[loc]; - - } else { - - int loc = Arrays.asList(period.getItemTP().getItems()).indexOf(item); - buys = period.getItemTP().getBuys()[loc]; - sells = period.getItemTP().getSells()[loc]; - - } - - } catch (NullPointerException e) { - - Main.getInstance().getLogger().severe( - "Error loading average buy and sell values for " + item); - - break; - - } - - finalBuys += buys; - finalSells += sells; - - } - - double avBuy = finalBuys / y; - double avSell = finalSells / y; - return new double[] { avBuy, avSell }; - - } - - /** - * Gets the max and min volatility for an item/enchantment. - * @param sectionName The section name. (shops or enchantments) - * @param item The item/enchantment. - * @return The max and min volatility. - */ - private double[] getMaxMinVolatility(String sectionName, String item) { - - Double maxVolatility = Config.getConfig().getMaxVolatility(); - Double minVolatility = Config.getConfig().getMinVolatility(); - - YamlConfiguration config = Main.getInstance().getDataFiles().getShops(); - - if (sectionName.equals("enchantments")) { - config = Main.getInstance().getDataFiles().getEnchantments(); - } - - maxVolatility = config.getConfigurationSection( - sectionName).getConfigurationSection(item).getDouble("max-volatility", maxVolatility); - - minVolatility = config.getConfigurationSection( - sectionName).getConfigurationSection(item).getDouble("min-volatility", minVolatility); - - double[] volatility = new double[2]; - volatility[0] = maxVolatility; - volatility[1] = minVolatility; - return volatility; - - } - -} diff --git a/src/main/java/unprotesting/com/github/events/async/SellPriceDifferenceUpdateEvent.java b/src/main/java/unprotesting/com/github/events/async/SellPriceDifferenceUpdateEvent.java deleted file mode 100644 index 2ca4efe..0000000 --- a/src/main/java/unprotesting/com/github/events/async/SellPriceDifferenceUpdateEvent.java +++ /dev/null @@ -1,57 +0,0 @@ -package unprotesting.com.github.events.async; - -import lombok.Getter; - -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -import unprotesting.com.github.Main; -import unprotesting.com.github.config.Config; - -public class SellPriceDifferenceUpdateEvent extends Event { - - @Getter - private final HandlerList handlers = new HandlerList(); - - /** - * Updates the sell price difference. - * @param isAsync Whether the event is being run async or not. - */ - public SellPriceDifferenceUpdateEvent(boolean isAsync) { - - super(isAsync); - - // If "sell-price-difference-variation-enabled" is false - // then don't update the sell price difference. - if (Config.getConfig().isSellPriceDifferenceVariationEnabled()) { - updateSellPriceDifference(); - } - - } - - private void updateSellPriceDifference() { - - double spd = Main.getInstance().getCache().getEconomyInfo().getSellPriceDifference(); - - double fraction = Config.getConfig().getSellPriceVariationUpdatePeriod() - / Config.getConfig().getSellPriceVariationTimePeriod(); - - double change = fraction * (Config.getConfig().getSellPriceDifferenceVariationStart() - - Main.getInstance().getDataFiles().getConfig().getDouble("sell-price-difference", 10)); - - double newSpd = spd - change; - - // If the new sell price difference is greater than the minimum then update it. - if (newSpd > Main.getInstance().getDataFiles().getConfig() - .getDouble("sell-price-difference", 15)) { - - Main.getInstance().getCache().getEconomyInfo().updateSellPriceDifference(newSpd); - - } - - Main.getInstance().getLogger().finer("Sell price difference changed from " - + spd + " to " + newSpd); - - } - -} diff --git a/src/main/java/unprotesting/com/github/events/sync/AutosellUpdateEvent.java b/src/main/java/unprotesting/com/github/events/sync/AutosellUpdateEvent.java deleted file mode 100644 index b75af59..0000000 --- a/src/main/java/unprotesting/com/github/events/sync/AutosellUpdateEvent.java +++ /dev/null @@ -1,99 +0,0 @@ -package unprotesting.com.github.events.sync; - -import java.util.ArrayList; -import java.util.List; - -import lombok.Getter; - -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.bukkit.inventory.ItemStack; - -import unprotesting.com.github.Main; -import unprotesting.com.github.commands.util.FunctionsUtil; - -public class AutosellUpdateEvent extends Event { - - @Getter - private final HandlerList handlers = new HandlerList(); - - private final YamlConfiguration config; - - /** - * Updates the autosell checker. - */ - public AutosellUpdateEvent() { - - config = Main.getInstance().getDataFiles().getPlayerData(); - - for (Player player : Bukkit.getOnlinePlayers()) { - runPlayerAutosellEvent(player); - } - - } - - /** - * Runs the autosell event for a player. - * @param player The player to run the event for. - */ - private void runPlayerAutosellEvent(Player player) { - - List data = getAutoSellItems(player); - - // If the data has two or more items in it then run the event. - // If the player is offline then skip the event. - if (data.size() < 1 || !player.isOnline()) { - return; - } - - ItemStack[] items = player.getInventory().getContents(); - - // Loop through the players inventory and check if any of the items - // are in the autosell list. - for (ItemStack item : items) { - - // If the item is null continue. - if (item == null) { - continue; - } - - // If the item is not in the autosell list continue. - if (!data.contains(item.getType().toString())) { - continue; - } - - player.getInventory().remove(item); - FunctionsUtil.sellCustomItem(player, item, true); - - } - - } - - private List getAutoSellItems(OfflinePlayer player) { - - List data = new ArrayList(); - - ConfigurationSection section = config.getConfigurationSection( - player.getUniqueId().toString() + ".autosell"); - - // If the section is null return. - if (section == null) { - return data; - } - - // Loop through the players autosell settings and add items that have - // been set to autosell. - for (String key : section.getKeys(false)) { - if (section.getBoolean(key)) { - data.add(key); - } - } - - return data; - } -} \ No newline at end of file diff --git a/src/main/java/unprotesting/com/github/events/sync/JoinMessageEventHandler.java b/src/main/java/unprotesting/com/github/events/sync/JoinMessageEventHandler.java deleted file mode 100644 index 12afeda..0000000 --- a/src/main/java/unprotesting/com/github/events/sync/JoinMessageEventHandler.java +++ /dev/null @@ -1,49 +0,0 @@ -package unprotesting.com.github.events.sync; - -import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; -import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; - -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.PlayerJoinEvent; - -import unprotesting.com.github.Main; -import unprotesting.com.github.config.Messages; -import unprotesting.com.github.util.UtilFunctions; - -public class JoinMessageEventHandler implements Listener { - - /** - * Handles the PlayerJoinEvent. - * @param e The PlayerJoinEvent. - * @see PlayerJoinEvent - */ - @EventHandler - public void onPlayerJoin(PlayerJoinEvent e) { - - double gdp = Main.getInstance().getCache().getGdpData().getGdp(); - double balance = Main.getInstance().getCache().getGdpData().getBalance(); - double loss = Main.getInstance().getCache().getGdpData().getLoss(); - double inflation = Main.getInstance().getCache().getGdpData().getInflation(); - double playerCount = Main.getInstance().getCache().getGdpData().getPlayerCount(); - - TagResolver resolver = TagResolver.resolver(Placeholder.parsed( - "player", e.getPlayer().getName()), - Placeholder.parsed("gdp", UtilFunctions.getDf().format(gdp)), - Placeholder.parsed("balance", UtilFunctions.getDf().format(balance)), - Placeholder.parsed("loss", UtilFunctions.getDf().format(loss)), - Placeholder.parsed("inflation", UtilFunctions.getDf().format(inflation)), - Placeholder.parsed("gdp-per-capita", UtilFunctions.getDf().format(gdp / playerCount)), - Placeholder.parsed("balance-per-capita", - UtilFunctions.getDf().format(balance / playerCount)), - Placeholder.parsed("loss-per-capita", UtilFunctions.getDf().format(loss / playerCount)), - Placeholder.parsed("inflation-per-capita", - UtilFunctions.getDf().format(inflation / playerCount))); - - // Loop through all the onJoin messages and send them to the player. - for (String message : Messages.getMessages().getOnJoin()) { - e.getPlayer().sendMessage(Main.getInstance().getMm().deserialize(message, resolver)); - } - - } -} diff --git a/src/main/java/unprotesting/com/github/events/sync/TutorialSendEvent.java b/src/main/java/unprotesting/com/github/events/sync/TutorialSendEvent.java deleted file mode 100644 index 596445e..0000000 --- a/src/main/java/unprotesting/com/github/events/sync/TutorialSendEvent.java +++ /dev/null @@ -1,67 +0,0 @@ -package unprotesting.com.github.events.sync; - -import java.util.HashMap; -import java.util.UUID; - -import lombok.Getter; - -import net.kyori.adventure.text.Component; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; - -import unprotesting.com.github.Main; -import unprotesting.com.github.config.Config; -import unprotesting.com.github.config.Messages; - -public class TutorialSendEvent extends Event { - - private static HashMap tutorialSteps = new HashMap<>(); - - @Getter - private final HandlerList handlers = new HandlerList(); - - /** - * Sends the tutorial messages. - */ - public TutorialSendEvent() { - - if (Config.getConfig().isTutorial()) { - sendTutorialMessages(); - } - - } - - private void sendTutorialMessages() { - - for (Player player : Bukkit.getOnlinePlayers()) { - - if (!player.hasPermission("at.tutorial")) { - continue; - } - - UUID uuid = player.getUniqueId(); - - if (tutorialSteps.containsKey(uuid)) { - - if (tutorialSteps.get(uuid) >= Messages.getMessages().getTutorial().size()) { - tutorialSteps.put(uuid, 0); - } else { - tutorialSteps.put(uuid, tutorialSteps.get(uuid) + 1); - } - - } else { - tutorialSteps.put(uuid, 0); - } - - Component message = Main.getInstance().getMm().deserialize( - Messages.getMessages().getTutorial().get(tutorialSteps.get(uuid))); - - player.sendMessage(message); - - } - - } -} diff --git a/src/main/java/unprotesting/com/github/events/sync/UnlockUpdateEvent.java b/src/main/java/unprotesting/com/github/events/sync/UnlockUpdateEvent.java deleted file mode 100644 index 42e39a6..0000000 --- a/src/main/java/unprotesting/com/github/events/sync/UnlockUpdateEvent.java +++ /dev/null @@ -1,177 +0,0 @@ -package unprotesting.com.github.events.sync; - -import java.util.ArrayList; -import java.util.List; - -import lombok.Getter; - -import org.bukkit.Bukkit; -import org.bukkit.OfflinePlayer; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.enchantments.Enchantment; -import org.bukkit.entity.Player; -import org.bukkit.event.Event; -import org.bukkit.event.HandlerList; -import org.bukkit.inventory.ItemStack; - -import unprotesting.com.github.Main; - -public class UnlockUpdateEvent extends Event { - - @Getter - private final HandlerList handlers = new HandlerList(); - - private static List lockableItems; - - /** - * Updates the unlock checker. - */ - public UnlockUpdateEvent() { - - if (lockableItems == null) { - loadLockableItems(); - } - - for (Player player : Bukkit.getOnlinePlayers()) { - runPlayerUnlockEvent(player); - } - - } - - /** - * Runs the unlock event for a player. - * @param player The player to run the event for. - */ - private void runPlayerUnlockEvent(Player player) { - - String uuid = player.getUniqueId().toString(); - ItemStack[] items = player.getInventory().getContents(); - - for (ItemStack item : items) { - runItemUnlockEvent(item, uuid); - } - - } - - /** - * Runs the unlock event for an item. - * @param item The item to run the event for. - * @param uuid The players uuid. - */ - private void runItemUnlockEvent(ItemStack item, String uuid) { - - if (item == null) { - return; - } - - if (lockableItems.contains(item.getType().toString())) { - addItem(item.getType().toString(), uuid); - } - - for (Enchantment enchantment : item.getEnchantments().keySet()) { - - if (lockableItems.contains(enchantment.toString())) { - addItem(enchantment.toString(), uuid); - } - - } - - } - - /** - * Adds an item to the players unlocked items. - * @param item The item to add. - * @param uuid The players uuid. - */ - private void addItem(String item, String uuid) { - - if (Main.getInstance().getDataFiles().getShops().getConfigurationSection("shops") - .getConfigurationSection(item) - .getString("collect-first-setting") - .equals("SERVER_WIDE")) { - - uuid = "server"; - - } - - YamlConfiguration config = Main.getInstance().getDataFiles().getPlayerData(); - - if (!config.contains(uuid + ".unlocked")) { - - config.createSection(uuid + ".unlocked"); - config.set(uuid + ".unlocked." + item, true); - Main.getInstance().getDataFiles().setPlayerData(config); - return; - - } - - if (!config.contains(uuid + ".unlocked." + item)) { - config.createSection(uuid + ".unlocked." + item); - config.set(uuid + ".unlocked." + item, true); - Main.getInstance().getDataFiles().setPlayerData(config); - } - - } - - /** - * Checks whether an item is locked. - * @param itemName The item to check. - * @param player The players uuid. - */ - public static boolean isUnlocked(OfflinePlayer player, String itemName) { - - if (lockableItems == null) { - loadLockableItems(); - } - - if (!lockableItems.contains(itemName)) { - return true; - } - - String uuid = player.getUniqueId().toString(); - - if (Main.getInstance().getDataFiles().getShops().getConfigurationSection("shops") - .getConfigurationSection(itemName) - .getString("collect-first-setting") - .equals("SERVER_WIDE")) { - - uuid = "server"; - - } - - if (Main.getInstance().getDataFiles().getPlayerData() - .contains(uuid + ".unlocked." + itemName)) { - - return Main.getInstance().getDataFiles().getPlayerData() - .getBoolean(uuid + ".unlocked." + itemName); - - } else { - return false; - } - - } - - /** - * Loads the lockable items. - */ - private static void loadLockableItems() { - - lockableItems = new ArrayList(); - - ConfigurationSection shops = Main.getInstance().getDataFiles() - .getShops().getConfigurationSection("shops"); - - for (String key : shops.getKeys(false)) { - - ConfigurationSection inner = shops.getConfigurationSection(key); - - if (!inner.getString("collect-first-setting", "NONE").equalsIgnoreCase("NONE")) { - lockableItems.add(key); - } - - } - } - - -} diff --git a/src/main/java/unprotesting/com/github/localserver/LocalServer.java b/src/main/java/unprotesting/com/github/localserver/LocalServer.java deleted file mode 100644 index 6973d5b..0000000 --- a/src/main/java/unprotesting/com/github/localserver/LocalServer.java +++ /dev/null @@ -1,44 +0,0 @@ -package unprotesting.com.github.localserver; - -import com.sun.net.httpserver.HttpServer; - -import java.net.InetSocketAddress; - -import unprotesting.com.github.Main; -import unprotesting.com.github.config.Config; - -public class LocalServer { - - private HttpServer server; - private String base = "plugins/Auto-Tune/web"; - - /** - * Start the local server. - */ - public LocalServer() { - - // If "web-server-enabled" is false, don't start the server. - if (!Config.getConfig().isWebServerEnabled()) { - return; - } - - try { - - server = HttpServer.create(new InetSocketAddress(Config.getConfig().getPort()), 0); - server.createContext("/", new StaticFileHandler(base)); - server.setExecutor(null); - server.start(); - - Main.getInstance().getLogger().info("Local server started on port " - + Config.getConfig().getPort()); - - } catch (Exception e) { - - Main.getInstance().getLogger().warning( - "Error Creating Server on port: " + Config.getConfig().getPort() - + ". Please try restarting or changing your port."); - - } - } - -} \ No newline at end of file diff --git a/src/main/java/unprotesting/com/github/localserver/StaticFileHandler.java b/src/main/java/unprotesting/com/github/localserver/StaticFileHandler.java deleted file mode 100644 index d5fdc42..0000000 --- a/src/main/java/unprotesting/com/github/localserver/StaticFileHandler.java +++ /dev/null @@ -1,55 +0,0 @@ -package unprotesting.com.github.localserver; - -import com.sun.net.httpserver.HttpExchange; -import com.sun.net.httpserver.HttpHandler; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; -import java.net.URI; -import java.nio.file.Files; - -import lombok.Cleanup; - -import unprotesting.com.github.Main; - -public class StaticFileHandler implements HttpHandler { - - private final String baseDir; - - /** - * StaticFileHandler constructor. - * @param baseDir The base directory of the static files. - */ - public StaticFileHandler(String baseDir) { - this.baseDir = baseDir; - } - - /** - * Handles the HTTP request. - * @param ex The HTTP exchange. - * @throws IOException If an error occurs. - */ - @Override - public void handle(HttpExchange ex) throws IOException { - - URI uri = ex.getRequestURI(); - String name = new File(uri.getPath()).getName(); - File path = new File(baseDir, name); - @Cleanup OutputStream out = ex.getResponseBody(); - - if (path.exists()) { - - ex.sendResponseHeaders(200, path.length()); - out.write(Files.readAllBytes(path.toPath())); - - } else { - - Main.getInstance().getLogger().warning("404 File not found: " + path.getAbsolutePath()); - ex.sendResponseHeaders(404, 0); - - } - - } - -} \ No newline at end of file diff --git a/src/main/java/unprotesting/com/github/util/AutoTuneLogger.java b/src/main/java/unprotesting/com/github/util/AutoTuneLogger.java new file mode 100644 index 0000000..3d58c3f --- /dev/null +++ b/src/main/java/unprotesting/com/github/util/AutoTuneLogger.java @@ -0,0 +1,149 @@ +package unprotesting.com.github.util; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import lombok.Getter; +import lombok.Setter; + +import org.bukkit.plugin.java.JavaPlugin; + +@Getter +@Setter +public class AutoTuneLogger { + + private Logger logger; + private Level level; + + public AutoTuneLogger(JavaPlugin plugin) { + this.logger = plugin.getLogger(); + this.level = Level.INFO; + } + + private static String prefix(Level level, String msg) { + return "[" + level.getName() + "] " + msg; + } + + private boolean shouldLog(Level level) { + return level.intValue() >= this.level.intValue(); + } + + /** + * Logs a message at the given level with an optional prefix. + * @param level the level to log at + * @param message the message to log + * @param param1 the parameters to use in the message + */ + public void log(Level level, String message, Object param1) { + if (shouldLog(level)) { + logger.log(Level.INFO, prefix(level, message), param1); + } + } + + /** + * Logs a message at the given level with optional prefixes. + * @param level the level to log at + * @param message the message to log + * @param params the parameters to log + */ + public void log(Level level, String message, Object... params) { + if (shouldLog(level)) { + logger.log(Level.INFO, prefix(level, message), params); + } + } + + + /** + * Logs a message at the given level. + */ + public void log(Level level, String message) { + if (shouldLog(level)) { + logger.log(Level.INFO, prefix(level, message)); + } + } + + public void fine(String message) { + log(Level.FINE, message); + } + + public void fine(String message, Object param1) { + log(Level.FINE, message, param1); + } + + public void fine(String message, Object... params) { + log(Level.FINE, message, params); + } + + public void finer(String message) { + log(Level.FINER, message); + } + + public void finer(String message, Object param1) { + log(Level.FINER, message, param1); + } + + public void finer(String message, Object... params) { + log(Level.FINER, message, params); + } + + public void finest(String message) { + log(Level.FINEST, message); + } + + public void finest(String message, Object param1) { + log(Level.FINEST, message, param1); + } + + public void finest(String message, Object... params) { + log(Level.FINEST, message, params); + } + + public void config(String message) { + log(Level.CONFIG, message); + } + + public void config(String message, Object param1) { + log(Level.CONFIG, message, param1); + } + + public void config(String message, Object... params) { + log(Level.CONFIG, message, params); + } + + public void info(String message) { + log(Level.INFO, message); + } + + public void info(String message, Object param1) { + log(Level.INFO, message, param1); + } + + public void info(String message, Object... params) { + log(Level.INFO, message, params); + } + + public void warning(String message) { + log(Level.WARNING, message); + } + + public void warning(String message, Object param1) { + log(Level.WARNING, message, param1); + } + + public void warning(String message, Object... params) { + log(Level.WARNING, message, params); + } + + public void severe(String message) { + log(Level.SEVERE, message); + } + + public void severe(String message, Object param1) { + log(Level.SEVERE, message, param1); + } + + public void severe(String message, Object... params) { + log(Level.SEVERE, message, params); + } + +} diff --git a/src/main/java/unprotesting/com/github/economy/EconomyFunctions.java b/src/main/java/unprotesting/com/github/util/EconomyUtil.java similarity index 54% rename from src/main/java/unprotesting/com/github/economy/EconomyFunctions.java rename to src/main/java/unprotesting/com/github/util/EconomyUtil.java index 338021b..b72ddbb 100644 --- a/src/main/java/unprotesting/com/github/economy/EconomyFunctions.java +++ b/src/main/java/unprotesting/com/github/util/EconomyUtil.java @@ -1,14 +1,16 @@ -package unprotesting.com.github.economy; +package unprotesting.com.github.util; import lombok.Getter; +import net.milkbowl.vault.economy.Economy; + import org.bukkit.Server; import org.bukkit.plugin.RegisteredServiceProvider; -public class EconomyFunctions { +public class EconomyUtil { @Getter - private static net.milkbowl.vault.economy.Economy economy; + private static Economy economy; /** * Initializes the economy. @@ -19,15 +21,9 @@ public static boolean setupLocalEconomy(Server server) { return setupEconomy(server); } - /** - * Initializes the economy. - * @param server The server. - * @return Whether the economy was initialized or not. - */ private static boolean setupEconomy(Server server) { - - RegisteredServiceProvider rsp = server.getServicesManager() - .getRegistration(net.milkbowl.vault.economy.Economy.class); + RegisteredServiceProvider rsp = server.getServicesManager() + .getRegistration(Economy.class); if (rsp == null) { return false; @@ -35,7 +31,6 @@ private static boolean setupEconomy(Server server) { economy = rsp.getProvider(); return economy != null; - } - + } diff --git a/src/main/java/unprotesting/com/github/util/Format.java b/src/main/java/unprotesting/com/github/util/Format.java new file mode 100644 index 0000000..1127b89 --- /dev/null +++ b/src/main/java/unprotesting/com/github/util/Format.java @@ -0,0 +1,163 @@ +package unprotesting.com.github.util; + +import java.text.DateFormat; +import java.text.NumberFormat; +import java.util.Locale; +import java.util.logging.Level; + +import lombok.Getter; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; + +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import unprotesting.com.github.AutoTune; + +public class Format { + + // The locale to use. + protected static Locale locale; + // The currency format. + protected static NumberFormat currency; + // The percentage format. + protected static NumberFormat percent; + // The decimal format. + protected static NumberFormat decimal; + // The number format. + protected static NumberFormat number; + // The mini message format. + protected static MiniMessage miniMessage; + // The date format + protected static DateFormat date; + // The logger + @Getter + protected static AutoTuneLogger log; + + /** + * Loads the locale and formats. + * @param localeString the locale string + */ + public static void loadLocale(String localeString) { + String[] localeSplit = localeString.split("_"); + locale = new Locale(localeSplit[0], localeSplit[1]); + currency = NumberFormat.getCurrencyInstance(locale); + percent = NumberFormat.getPercentInstance(locale); + percent.setMaximumFractionDigits(2); + decimal = NumberFormat.getNumberInstance(locale); + decimal.setMaximumFractionDigits(2); + number = NumberFormat.getNumberInstance(locale); + date = DateFormat.getDateInstance(DateFormat.SHORT, locale); + miniMessage = MiniMessage.miniMessage(); + } + + /** + * Loads the logger. + */ + public static void loadLogger(Level level) { + log = new AutoTuneLogger(AutoTune.getInstance()); + log.setLevel(level); + log.info("Logger loaded with level " + log.getLevel().toString()); + } + + /** + * Format a number to a currency string. + * @param amount the amount to format + * @return the formatted currency string + */ + public static String currency(double amount) { + return currency.format(amount); + } + + /** + * Format a number to a percentage string. + * @param amount the amount to format + * @return the formatted percentage string + */ + public static String percent(double amount) { + return percent.format(amount); + } + + /** + * Format a number to a decimal string. + * @param amount the amount to format + * @return the formatted decimal string + */ + public static String decimal(double amount) { + return decimal.format(amount); + } + + /** + * Format a number to a number string. + * @param amount the amount to format + * @return the formatted number string + */ + public static String number(double amount) { + return number.format(amount); + } + + /** + * Format a millis long to a date. + * @param time the time to format + * @return the formatted date string + */ + public static String date(long time) { + return date.format(time); + } + + + /** + * Send a message to a player using the MiniMessage API and a tag resolver. + * @param player the player to send the message to + * @param message the message to send + * @param resolver the tag resolver + */ + public static void sendMessage(Player player, String message, TagResolver resolver) { + player.sendMessage(miniMessage.deserialize(message, resolver)); + } + + /** + * Send a message to a player using the MiniMessage API. + * @param player the player to send the message to + * @param message the message to send + */ + public static void sendMessage(Player player, String message) { + player.sendMessage(miniMessage.deserialize(message)); + } + + /** + * Send a message to a CommandSender using the MiniMessage API and a tag resolver. + * @param sender The command sender + * @param message The message to send + * @param resolver The tag resolver + */ + public static void sendMessage(CommandSender sender, String message, TagResolver resolver) { + sender.sendMessage(miniMessage.deserialize(message, resolver)); + } + + /** + * Send a message to a CommandSender using the MiniMessage API. + * @param sender The command sender + * @param message The message to send + */ + public static void sendMessage(CommandSender sender, String message) { + sender.sendMessage(miniMessage.deserialize(message)); + } + + /** + * Get the component of a message using the MiniMessage API and a tag resolver. + */ + public static Component getComponent(String message, TagResolver resolver) { + return miniMessage.deserialize(message, resolver); + } + + /** + * Get the component of a message using the MiniMessage API. + */ + public static Component getComponent(String message) { + return miniMessage.deserialize(message); + } + +} diff --git a/src/main/java/unprotesting/com/github/util/MathUtil.java b/src/main/java/unprotesting/com/github/util/MathUtil.java new file mode 100644 index 0000000..6b5059a --- /dev/null +++ b/src/main/java/unprotesting/com/github/util/MathUtil.java @@ -0,0 +1,31 @@ +package unprotesting.com.github.util; + +public class MathUtil { + + /** + * Add up all the values in an integer array. + * @param array The array to add up + * @return The sum of all the values in the array + */ + public static int sumIntArray(int[] array) { + int sum = 0; + for (int i : array) { + sum += i; + } + return sum; + } + + /** + * Add up all the values in a double array. + * @param array The array to add up + * @return The sum of all the values in the array + */ + public static double sumDoubleArray(double[] array) { + double sum = 0; + for (double i : array) { + sum += i; + } + return sum; + } + +} diff --git a/src/main/java/unprotesting/com/github/util/UtilFunctions.java b/src/main/java/unprotesting/com/github/util/UtilFunctions.java index 1106937..415e279 100644 --- a/src/main/java/unprotesting/com/github/util/UtilFunctions.java +++ b/src/main/java/unprotesting/com/github/util/UtilFunctions.java @@ -1,24 +1,13 @@ package unprotesting.com.github.util; +import com.earth2me.essentials.Essentials; import com.earth2me.essentials.User; -import java.text.DecimalFormat; - -import lombok.Getter; -import lombok.Setter; - import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import unprotesting.com.github.Main; -import unprotesting.com.github.config.Config; - public class UtilFunctions { - @Getter - @Setter - private static DecimalFormat df; - /** * Calculates the number of players online. * @return The number of players online. @@ -48,70 +37,20 @@ public static int calculatePlayerCount() { * @return Value to add to the player count */ public static int shouldAddOne(Player player) { + Essentials ess = (Essentials) Bukkit.getServer().getPluginManager().getPlugin("Essentials"); - User user = new User(player, Main.getInstance().getEss()); - - // If "ignore-afk" is disabled, add one to the player count. - if (!Config.getConfig().isIgnoreAfk()) { + if (ess == null) { return 1; } + User user = new User(player, ess); + // If user if AFK or vanished and "ignore-afk" is enabled, don't add one to the player count. if (user.isAfk() || user.isVanished()) { return 0; } return 1; - } - - /** - * Calculates the new price of an item using the pricing formula. - * - *

If buys > sells then: - * - *

- * price = p + p * v1 * 0.01 * (b/(b+s)) + p * v2 * 0.01 - * - * - *

If sells > buys then: - * - *

- * price = p - p * v1 * 0.01 * (s/(b+s)) - p * v2 * 0.01 - * - * - *

Where: - * - *

p is the previous price. - * - *

v1 is the max volatility. - * - *

v2 is the min volatility. - * - *

b is the average buy value. - * - *

s is the average sell value. - * - * @param p The previous price. - * @param volatility The volatility. - * @param b The average buy value. - * @param s The average sell value. - * @return The new price. - */ - public static double calculateNewPrice(double p, double[] volatility, double b, double s) { - - double total = b + s; - - // Check if buys > sells and calculate the new price based on the formula. - if (b > s) { - return p + p * volatility[0] * 0.01 * (b / total) + p * 0.01 * volatility[1]; - } else if (b < s) { - return p - p * volatility[0] * 0.01 * (s / total) - p * 0.01 * volatility[1]; - } else { - return p; - } - - } - - + } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 97b6784..915b726 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,139 +1,41 @@ - -# ░█████╗░██╗░░░██╗████████╗░█████╗░░░░░░░████████╗██╗░░░██╗███╗░░██╗███████╗ -# ██╔══██╗██║░░░██║╚══██╔══╝██╔══██╗░░░░░░╚══██╔══╝██║░░░██║████╗░██║██╔════╝ -# ███████║██║░░░██║░░░██║░░░██║░░██║█████╗░░░██║░░░██║░░░██║██╔██╗██║█████╗░░ -# ██╔══██║██║░░░██║░░░██║░░░██║░░██║╚════╝░░░██║░░░██║░░░██║██║╚████║██╔══╝░░ -# ██║░░██║╚██████╔╝░░░██║░░░╚█████╔╝░░░░░░░░░██║░░░╚██████╔╝██║░╚███║███████╗ -# ╚═╝░░╚═╝░╚═════╝░░░░╚═╝░░░░╚════╝░░░░░░░░░░╚═╝░░░░╚═════╝░╚═╝░░╚══╝╚══════╝ - -## -- Auto-Tune Config File -- ## - -## See the wiki for info on each setting: https://github.com/Unprotesting/Auto-Tune/wiki - -## -- General Settings -- ## - -## Enable/Disable integrated Web Server. -## Info: Use /trade to view the web-server -web-server-enabled: true - -## Port for integrated Web Server (If enabled) -## Make sure to port-forward and disable firewalls for this port. -port: 8123 - -## Time Period in minutes -## Info: When decreasing or increasing this adjust your volatility settings accordingly -time-period: 30 - -## GUI Shop Menu title -menu-title: 'Shop' - -## GUI Shop Menu background -## Info: Use 'NONE' for no background -background: 'BLACK_STAINED_GLASS_PANE' - -## How often auto-sell updates in ticks -## Info: Set this higher if few players use autosell -## Info: Set it lower if many players use autosell -auto-sell-update-period: 10 - -## How often players are shown their auto-sell profits in ticks -auto-sell-profit-update-period: 600 - -## Global number format -number-format: '###,###,###,###,##0.00' - -## Enable Enchantments -enable-enchantments: true - -## -- Pricing Model Settings -- ## - -## Percentage difference in sell price to buy price -sell-price-difference: 15.0 - -## Maximum Volatility per Time Period for the Variable Volatility price calculation algorithm as a percentage of total price -max-volatility: 0.5 - -## Minimum Volatility per Time Period for the Fixed Volatility price calculation algorithm in economy units -min-volatility: 0.05 - -## -- Data Selection Settings -- ## - -## Info: When setting your data selection algorithm use a site such as https://www.desmos.com/calculator -## Info: Data selection uses the equation y=m(x^z)+c, for example the default is y=0.075(x^(1.6))+0.55 - -## 'm' in equation: y=m(x^z)+c -data-selection-m: 0.05 - -## 'z' in equation: y=m(x^z)+c -data-selection-z: 1.75 - -## 'c' in equation: y=m(x^z)+c -data-selection-c: 0.55 - -## -- Other Economy Settings -- - -## Minimum players needed, to be online, for prices to update -## Info: It is recommended to keep this above 0 -update-prices-threshold: 1 - -## The symbol that appears before all currency -currency-symbol: '$' - -## Enable sell price difference variation to ease out sell price variation -sell-price-difference-variation-enabled: true - -## Starting percentage sell price difference for sell price variation -sell-price-difference-variation-start: 30.0 - -## Time in minutes until sell price reaches sell-price-difference set in pricing model settings (default 4 weeks) -sell-price-variation-time-period: 43200 - -## Time in minutes that the sell-price-difference updates -sell-price-variation-update-period: 30 - -## Interest rate per interest-rate-update-period -## Info: This is the increase in the current debt payment per-time period -interest-rate: 0.05 - -## Time period in ticks between updates of the interest rate for users loans -interest-rate-update-period: 1200 - -## Disable the max-buy/max-sells for items -## Info: Don't do this unless you know what your doing. -## Info: If this is enabled, it is likely to lead to exploitation on servers with under 10 concurrent players -disable-max-buys-sells: false - -## The lowest value in $ a player can go into debt -## For example if a player has $3,000 and this is set to 1000 a player can take out a loan up to $2,000 -max-debt-value: 1000.0 - -## The percentage value to decrease items sold with enchantments -## Info: This value should be above 0 because it limits the exploit-ability of enchantments -## Info: This doesn't affect the buy-price. -enchantment-limiter: 10.0 - -## The percentage value to decrease items sold with a loss in durability -## Info: This is applied ON TOP of the durability algorithm to limit the exploit-ability of selling tools -durability-limiter: 15.0 - -## -- Other Settings -- - -## Ignore AFK players in price calculations/online checks -## Info: Turning this on will mean the price will only update when there's a player that is not AFK -## Info: This only applies to essentials AFK and you must have essentials installed for this to work -ignore-afk: true - -## Enable the Auto-Tune tutorial for players (the messages that are displayed to players periodically) -## Keep this on to encourage purchasing turn it off if it is distracting -tutorial: true - -## Time in seconds between messages -tutorial-message-period: 360 - -## Data storage location -data-location: 'plugins/Auto-Tune/' - -## The level of the logger to use -## Info: This is the level of logging that is outputted to the console -## Info: Possible values are: SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST -log-level: 'INFO' +# The default rate that prices are updated. Every price update the max-buys and sells are also reset. +# Increase this for low player counts, decrease for high player counts. +time-period: 10 + +# The default maximum change in a given time-period for an item. +# Increase this for high player counts, decrease for low player counts. +volatility: 0.25 + +# The default percentage difference in the sell price from the buy price. +# Increase this for low player counts, decrease for high player counts. +sell-price-difference: 20 + +# The minimum number of players required to be online to run price updates. +# If your servers prices are all over the place this is a good option to increase. +# It helps to limit price exploits for sensitive items. +# If your servers prices aren't changing check there are enough players online. +minimum-players: 2 + +# The interest applied on loans each minute. +# If inflation is to high you can increase this. +# If inflation is to low you can decrease this. +interest: 0.05 + +# The rate that the tutorial messages are sent. +# If they are getting annoying you can increase this value. +tutorial-update: 300 + +# The port of the web-server. +port: 8989 + +# The background for GUI's. +background: "BLACK_STAINED_GLASS_PANE" + +# The log level, can be one of the following: +# SEVERE, WARNING, INFO, CONFIG, FINE, FINER, FINEST, ALL. +# The default log level is INFO. +# This will log all messages with the level or above. +log-level: "INFO" + +# The locale to use for formatting. +locale: "en_US" \ No newline at end of file diff --git a/src/main/resources/enchantments.yml b/src/main/resources/enchantments.yml deleted file mode 100644 index 2cb12df..0000000 --- a/src/main/resources/enchantments.yml +++ /dev/null @@ -1,175 +0,0 @@ - -# ░█████╗░██╗░░░██╗████████╗░█████╗░░░░░░░████████╗██╗░░░██╗███╗░░██╗███████╗ -# ██╔══██╗██║░░░██║╚══██╔══╝██╔══██╗░░░░░░╚══██╔══╝██║░░░██║████╗░██║██╔════╝ -# ███████║██║░░░██║░░░██║░░░██║░░██║█████╗░░░██║░░░██║░░░██║██╔██╗██║█████╗░░ -# ██╔══██║██║░░░██║░░░██║░░░██║░░██║╚════╝░░░██║░░░██║░░░██║██║╚████║██╔══╝░░ -# ██║░░██║╚██████╔╝░░░██║░░░╚█████╔╝░░░░░░░░░██║░░░╚██████╔╝██║░╚███║███████╗ -# ╚═╝░░╚═╝░╚═════╝░░░░╚═╝░░░░╚════╝░░░░░░░░░░╚═╝░░░░╚═════╝░╚═╝░░╚══╝╚══════╝ - -## -- Auto-Tune Enchantments File -- ## - -config: - position: 22 - block: 'ENCHANTED_BOOK' - background: 'GRAY_STAINED_GLASS_PANE' - back-menu-button-enabled: true - display-name: 'Enchantments Shop' - -enchantments: - power: - price: 300.00 ## <- An added price for buying/selling an item with this enchantment - ratio: 0.15 ## <- Another added percentage of the item bought/sold with this enchantment - ## Info: An item worth usually 100 will cost (100*0.3)+600=630 - ## Provides extra damage when shooting arrows from bows - ## sell-price-difference: 10.0 <- Add a custom sell-price-difference - ## locked: true <- Example of a locked item - ## max-volatility: 1.0 <- Add a custom max-volatility - ## min-volatility: 0.1 <- Add a custom min-volatility - flame: - price: 350.00 - ratio: 0.2 - ## Sets entities on fire when hit by arrows shot from a bow - infinity: - price: 750.00 - ratio: 0.3 - ## Provides infinite arrows when shooting a bow - punch: - price: 450.00 - ratio: 0.2 - ## Provides a knockback when an entity is hit by an arrow from a bow - binding_curse: - price: 40.00 - ratio: 0.05 - ## Item cannot be removed - channeling: - price: 300.00 - ratio: 0.5 - ## Strikes lightning when a mob is hit with a trident if conditions are stormy - sharpness: - price: 350.00 - ratio: 0.2 - ## Increases damage against all targets - bane_of_arthropods: - price: 350.00 - ratio: 0.4 - ## Increases damage against arthropod targets - smite: - price: 350.00 - ratio: 0.2 - ## Increases damage against undead targets - depth_strider: - price: 450.00 - ratio: 0.2 - ## Increases walking speed while in water - efficiency: - price: 450.00 - ratio: 0.2 - ## Increases the rate at which you mine/dig - unbreaking: - price: 450.00 - ratio: 0.15 - ## Decreases the rate at which a tool looses durability - fire_aspect: - price: 500.00 - ratio: 0.25 - ## When attacking a target, has a chance to set them on fire - frost_walker: - price: 550.00 - ratio: 0.25 - ## Freezes any still water adjacent to ice / frost which player is walking on - impaling: - price: 300.00 - ratio: 0.2 - ## Deals more damage to mobs that live in the ocean - knockback: - price: 500.00 - ratio: 0.2 - ## All damage to other targets will knock them back when hit - fortune: - price: 600.00 - ratio: 0.3 - ## Provides a chance of gaining extra loot when destroying blocks - looting: - price: 600.00 - ratio: 0.15 - ## Provides a chance of gaining extra loot when killing monsters - loyalty: - price: 550.00 - ratio: 0.2 - ## Causes a thrown trident to return to the player who threw it - luck_of_the_sea: - price: 350.00 - ratio: 0.15 - ## Decreases odds of catching worthless junk - lure: - price: 250.00 - ratio: 0.1 - ## Increases rate of fish biting your hook - mending: - price: 2000.00 - ratio: 0.3 - ## Allows mending the item using experience orbs - multishot: - price: 400.00 - ratio: 0.1 - ## Shoot multiple arrows from crossbows - respiration: - price: 300.00 - ratio: 0.1 - ## Decreases the rate of air loss whilst underwater - piercing: - price: 350.00 - ratio: 0.1 - ## Crossbow projectiles pierce entities - protection: - price: 450.00 - ratio: 0.15 - ## Provides protection against environmental damage - blast_protection: - price: 450.00 - ratio: 0.2 - ## Provides protection against explosive damage - feather_falling: - price: 450.00 - ratio: 0.15 - ## Provides protection against fall damage - fire_protection: - price: 450.00 - ratio: 0.2 - ## Provides protection against fire damage - projectile_protection: - price: 450.00 - ratio: 0.2 - ## Provides protection against projectile damage - quick_charge: - price: 400.00 - ratio: 0.2 - ## Charges crossbows quickly - riptide: - price: 500.00 - ratio: 0.2 - ## When it is rainy, launches the player in the direction their trident is thrown - silk_touch: - price: 650.00 - ratio: 0.3 - ## Allows blocks to drop themselves instead of fragments (for example, stone instead of cobblestone) - soul_speed: - price: 600.00 - ratio: 0.2 - ## Walk quicker on soul blocks - sweeping: - price: 500.00 - ratio: 0.2 - ## Increases damage against targets when using a sweep attack - thorns: - price: 600.00 - ratio: 0.3 - ## Damages the attacker - vanishing_curse: - price: 20.00 - ratio: 0.05 - ## Item disappears instead of dropping - aqua_affinity: - price: 350.00 - ratio: 0.15 - ## Increases the speed at which a player may mine underwater \ No newline at end of file diff --git a/src/main/resources/messages.yml b/src/main/resources/messages.yml index 3212677..3f8a779 100644 --- a/src/main/resources/messages.yml +++ b/src/main/resources/messages.yml @@ -1,75 +1,66 @@ - -# ░█████╗░██╗░░░██╗████████╗░█████╗░░░░░░░████████╗██╗░░░██╗███╗░░██╗███████╗ -# ██╔══██╗██║░░░██║╚══██╔══╝██╔══██╗░░░░░░╚══██╔══╝██║░░░██║████╗░██║██╔════╝ -# ███████║██║░░░██║░░░██║░░░██║░░██║█████╗░░░██║░░░██║░░░██║██╔██╗██║█████╗░░ -# ██╔══██║██║░░░██║░░░██║░░░██║░░██║╚════╝░░░██║░░░██║░░░██║██║╚████║██╔══╝░░ -# ██║░░██║╚██████╔╝░░░██║░░░╚█████╔╝░░░░░░░░░██║░░░╚██████╔╝██║░╚███║███████╗ -# ╚═╝░░╚═╝░╚═════╝░░░░╚═╝░░░░╚════╝░░░░░░░░░░╚═╝░░░░╚═════╝░╚═╝░░╚══╝╚══════╝ - -## -- Auto-Tune Messages File -- ## - -## See the wiki for info on each setting: https://github.com/Unprotesting/Auto-Tune/wiki - -## Buying items # Placeholders: , , , , -not-enough-money: "You need $ to purchase ." -run-out-of-buys: "You have run out of buys for ." -not-enough-space: "Not enough space in inventory." -not-unlocked: "You need to unlock this item by collecting it to purchase it." -not-in-shop: "The item you are trying to purchase is not in the shop." -shop-purchase: "Purchased x of for $." +not-in-shop: "This item is not in the shop." +not-enough-money: "You need to purchase ." +not-enough-space: "Not enough space in inventory." +not-enough-items: "You don't have x to sell." +not-unlocked: "This item is not unlocked, it must be found by the first." +run-out-of-buys: "You have run out of buys for ." +run-out-of-sells: "You have run out of sells for ." +shop-purchase: "Purchased x of for ." +shop-sell: "Sold x of for ." +hold-item-in-hand: "Hold the item you want to enchant in your hand!" +enchantment-error: "Cannot enchant with enchantment." -## Selling items -# Placeholders: , , , , -do-not-have-item: "You do not have ." -run-out-of-sells: "You have run out of sells for ." -shop-sell: "Sold x of for $." +# Placeholders: , +autosell-profit: "Your items were sold and has been added to your account." -## Buying enchantments -# Placeholders: , , , -hold-item-in-hand: "Hold the item you want to enchant in your hand!" -not-enough-money-enchantments: "You need $ to purchase this enchantment." -enchantment-error: "Cannot enchant with enchantment." -enchantment-purchase: "Purchased for $" +invalid-shop-section: "Invalid shop section." -## Selling custom items -# Placeholders: , , , -cannot-sell-custom: "Cannot sell ." -sell-custom-item: "Sold x of for $." +# Placeholders: , , , , , , , +shop-lore: + - "Price: " + - "Sell Price: " + - "Buys Left: /" + - "Sells Left: /" + - "Change: " -## Auto-selling items -# Placeholders: , -autosell-profit-update: "Your items were sold and $ has been added to your account." +# Placeholders , , , , , , , , +# The first line is the display-name, the other lines are the lore. +shop-gdp-lore: + - "Server Economy Information" + - "GDP per capita: " + - "Debt per capita: " + - "Loss per capita: " + - "Balance per capita: " + - "Inflation: " -## Loans -# Placeholders: , , -loan-success: "You have taken a loan of $ with an interest rate of % per $min(s).." +# Placeholders: , , , , , , , , , , +purchase-buy-lore: + - "Price: " + - "Buys Left: /" + - "Change: " + - "Collect first setting: " -## Message when a player doesn't have permission to perform a command -no-permission: "You do not have permission to perform this command." +# Placeholders: , , , , , , , , , , +purchase-sell-lore: + - "Sell Price: " + - "Sells Left: /" + - "Change: " + +# Placeholders +autosell-lore: + - "Auto-sell setting: " -## Tutorial messages -## These messages are displayed in this order from a player joining tutorial: - 'Do /shop to open the shop and start exchanging items.' - 'Do /sell to sell items quickly.' - 'Control the market! Your purchases rise prices.' - 'Control the market! Your sales lower prices.' - 'Do /autosell to sell items automatically.' - - 'Do /trade to view item prices over time.' - 'Do /loan to view your loans. Do /loan to loan money.' - - 'Do /gdp to view the server GDP info.' - 'Watch the prices of items! They can go up and down.' - 'There are big profits to be made when prices change..' - 'Loan money to buy items and take advantage of the rise in prices.' - 'Sell items that have high demand to make the most money selling.' - 'Using /autosell allows you to make money quickly and easily' - - 'Using /loan to loan money allows you to invest to make even more money.' - - 'Viewing prices with /trade allows you to judge the markets.' - -## Join messages -## These message are displayed when a player joins -# Placeholders: , , , , , , , , -on-join: - - 'GDP per-capita: $' - - 'Average player balance: $' \ No newline at end of file + - 'Using /loan to loan money allows you to invest to make even more money.' \ No newline at end of file diff --git a/src/main/resources/playerdata.yml b/src/main/resources/playerdata.yml index 9ed90ab..481de7f 100644 --- a/src/main/resources/playerdata.yml +++ b/src/main/resources/playerdata.yml @@ -1,11 +1,4 @@ - -# ░█████╗░██╗░░░██╗████████╗░█████╗░░░░░░░████████╗██╗░░░██╗███╗░░██╗███████╗   -# ██╔══██╗██║░░░██║╚══██╔══╝██╔══██╗░░░░░░╚══██╔══╝██║░░░██║████╗░██║██╔════╝   -# ███████║██║░░░██║░░░██║░░░██║░░██║█████╗░░░██║░░░██║░░░██║██╔██╗██║█████╗░░   -# ██╔══██║██║░░░██║░░░██║░░░██║░░██║╚════╝░░░██║░░░██║░░░██║██║╚████║██╔══╝░░   -# ██║░░██║╚██████╔╝░░░██║░░░╚█████╔╝░░░░░░░░░██║░░░╚██████╔╝██║░╚███║███████╗   -# ╚═╝░░╚═╝░╚═════╝░░░░╚═╝░░░░╚════╝░░░░░░░░░░╚═╝░░░░╚═════╝░╚═╝░░╚══╝╚══════╝   - -## -- Auto-Tune PlayerData File -- ## - -## This is the empty playerdata.yml file, it stores players data such as autoselling settings. \ No newline at end of file +autosell: + b4aff885-45ff-464f-8a30-8fd09b8bd6d3: + granite: true + diorite: true \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 6df67c8..618a184 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,90 +1,53 @@ - -# ░█████╗░██╗░░░██╗████████╗░█████╗░░░░░░░████████╗██╗░░░██╗███╗░░██╗███████╗ -# ██╔══██╗██║░░░██║╚══██╔══╝██╔══██╗░░░░░░╚══██╔══╝██║░░░██║████╗░██║██╔════╝ -# ███████║██║░░░██║░░░██║░░░██║░░██║█████╗░░░██║░░░██║░░░██║██╔██╗██║█████╗░░ -# ██╔══██║██║░░░██║░░░██║░░░██║░░██║╚════╝░░░██║░░░██║░░░██║██║╚████║██╔══╝░░ -# ██║░░██║╚██████╔╝░░░██║░░░╚█████╔╝░░░░░░░░░██║░░░╚██████╔╝██║░╚███║███████╗ -# ╚═╝░░╚═╝░╚═════╝░░░░╚═╝░░░░╚════╝░░░░░░░░░░╚═╝░░░░╚═════╝░╚═╝░░╚══╝╚══════╝ - -## -- Auto-Tune Plugin File -- ## - -main: unprotesting.com.github.Main +main: unprotesting.com.github.AutoTune name: Auto-Tune -version: 0.13.1 -author: Unprotesting -description: Automatic Economy Plugin +description: "The Auto-Tune plugin is an economy plugin that automatically regulates prices based on supply and demand." +author: "Unprotesting" +version: "0.14.0-pre-release" softdepend: - - Essentials -depend: [Vault] -api-version: 1.14 -website: https://github.com/Unprotesting/Auto-Tune -prefix: 'Auto-Tune' + - "Essentials" +depend: + - "Vault" +libraries: + - "org.eclipse.collections:eclipse-collections-api:11.0.0" + - "org.eclipse.collections:eclipse-collections:11.0.0" + - "org.eclipse.collections:eclipse-collections-forkjoin:11.0.0" + - "com.google.guava:guava:31.1-jre" + - "net.jpountz.lz4:lz4:1.3.0" + - "org.jetbrains.kotlin:kotlin-stdlib:1.7.0" +api-version: 1.13 +website: "https://github.com/Unprotesting/Auto-Tune" +prefix: "Auto-Tune" commands: - at: - description: Change item prices and force price-updates. - usage: / - aliases: [autotune] - trade: - description: Trade Online with other players. - usage: / - aliases: [pricehistory, onlinepricehistory] - shop: - description: GUIShop alias for buy and sell commands. - usage: / - sell: - description: Sell items quickly to the shop. - usage: / - autosell: - description: Auto-Tune Auto Sell Command - usage: / - loan: - description: Auto-Tune Auto Loan Command - usage: / - gdp: - description: View GDP info - usage: /GDP - buy: - description: Buy items not available in the shop - aliases: [purchase] - transactions: - description: View player transactions - usage: /transactions | /transactions -p + shop: + description: "Opens the shop." + usage: "/shop " + permission: "autotune.shop" + permission-message: "You don't have permission to use this command." + sell: + description: "Opens the sell menu." + usage: "/sell" + permission: "autotune.sell" + permission-message: "You don't have permission to use this command." + autosell: + description: "Opens the autosell menu." + usage: "/autosell" + permission: "autotune.autosell" + permission-message: "You don't have permission to use this command." + loan: + description: "Allows players to loan money." + usage: "/loan /pay" + permission: "autotune.loan" + permission-message: "You don't have permission to use this command." permissions: - at.admin: - description: Admin commands and access to all other commands. - at.autosell: - description: Open the auto-sell GUI and use automatic selling. + autotune.shop: + description: "Allows the user to use the shop." default: true - at.gdp: - description: View GDP and other server info. + autotune.sell: + description: "Allows the user to use the sell menu." default: true - at.loan: - description: Loan money from the bank and view loans. + autotune.autosell: + description: "Allows the user to use the autosell menu." default: true - at.loan.other: - description: View and interact with other players loans. - default: false - at.sell: - description: Open the sell GUI and sell items. - default: true - at.shop: - description: Open the GUI shop to buy/sell items. - default: true - at.trade: - description: Access the integrated web-server to view item prices. - default: true - at.transactions: - description: View your own transactions history. - default: true - at.transactions.other: - description: View all transactions. - default: op - at.tutorial: - description: Allow players to view tutorial messages. - default: true - - - - - - + autotune.loan: + description: "Allows the user to use the loan command." + default: true \ No newline at end of file diff --git a/src/main/resources/shops.yml b/src/main/resources/shops.yml index 7dc28b9..ef33a45 100644 --- a/src/main/resources/shops.yml +++ b/src/main/resources/shops.yml @@ -1,642 +1,765 @@ +sections: + ores: + # The display name for the section. + display: Natural Resources + # The item to use for this section. + image: iron_ore + # The x and y coordinates for the section. + x: 1 + y: 1 + blocks: + display: Blocks + image: stone + x: 3 + y: 1 + food: + display: Food + image: bread + x: 5 + y: 1 + farming: + display: Farming + image: wheat + x: 7 + y: 1 + tools: + display: Tools + image: iron_pickaxe + x: 2 + y: 3 + enchantments: + display: Enchantments + image: enchanted_book + x: 4 + y: 3 + other: + display: Misc + image: music_disc_cat + x: 6 + y: 3 -# ░█████╗░██╗░░░██╗████████╗░█████╗░░░░░░░████████╗██╗░░░██╗███╗░░██╗███████╗   -# ██╔══██╗██║░░░██║╚══██╔══╝██╔══██╗░░░░░░╚══██╔══╝██║░░░██║████╗░██║██╔════╝   -# ███████║██║░░░██║░░░██║░░░██║░░██║█████╗░░░██║░░░██║░░░██║██╔██╗██║█████╗░░   -# ██╔══██║██║░░░██║░░░██║░░░██║░░██║╚════╝░░░██║░░░██║░░░██║██║╚████║██╔══╝░░   -# ██║░░██║╚██████╔╝░░░██║░░░╚█████╔╝░░░░░░░░░██║░░░╚██████╔╝██║░╚███║███████╗   -# ╚═╝░░╚═╝░╚═════╝░░░░╚═╝░░░░╚════╝░░░░░░░░░░╚═╝░░░░╚═════╝░╚═╝░░╚══╝╚══════╝   +# Format for shops: +# diamond: -> The item id + # price: 400 -> The price of the item + # sell-price-difference: 25 -> Define a custom sell price difference. + # max-buy: 12 -> The maximum buys for this item per time period. + # max-sell: 24 -> The maximum sells for this item per time period. + # collect-first: player -> Whether the item needs to be collected by the player or server before it can be bought. (Default: server) + # update-rate: 3 -> Define a custom update rate, 3 is 3x the default time period. -## -- Auto-Tune Shops File -- ## +shops: + ores: + coal: + price: 15 + max-buy: 80 + max-sell: 115 + iron_ingot: + price: 17 + max-buy: 75 + max-sell: 115 + copper_ingot: + price: 12 + max-buy: 100 + max-sell: 200 + gold_ingot: + price: 25 + max-buy: 64 + max-sell: 100 + diamond: + price: 400 + sell-price-difference: 25 + max-buy: 12 + max-sell: 24 + collect-first: player + update-rate: 3 + amethyst_shard: + price: 22 + max-buy: 32 + max-sell: 50 + lapis_lazuli: + price: 12 + max-buy: 128 + max-sell: 256 + emerald: + price: 150 + max-buy: 16 + max-sell: 32 + collect-first: player + update-rate: 2 + quartz: + price: 10 + max-buy: 64 + max-sell: 150 + redstone: + price: 7.5 + max-buy: 90 + max-sell: 175 + netherite_ingot: + price: 5000 + sell-price-difference: 35 + max-buy: 1 + max-sell: 1 + update-rate: 5 + collect-first: player + glowstone_dust: + price: 3.5 + max-buy: 128 + max-sell: 200 + blocks: + dirt: + price: 0.55 + sell-price-difference: 12.5 + max-buy: 512 + max-sell: 1024 + collect-first: none + volatility: 0.5 + grass_block: + price: 5 + max-buy: 32 + max-sell: 64 + collect-first-setting: player + cobblestone: + price: 0.95 + sell-price-difference: 15 + max-buy: 250 + max-sell: 750 + collect-first: none + volatility: 0.3 + stone: + price: 2 + max-buy: 128 + max-sell: 256 + gravel: + price: 3 + max-buy: 128 + max-sell: 256 + sand: + price: 1.15 + sell-price-difference: 15 + max-buy: 300 + max-sell: 600 + collect-first: none + volatility: 0.35 + glass: + price: 2.25 + max-buy: 128 + max-sell: 256 + sandstone: + price: 4 + max-buy: 100 + max-sell: 225 + obsidian: + price: 15 + max-buy: 20 + max-sell: 45 + collect-first: player + end_stone: + price: 3.25 + max-buy: 75 + max-sell: 150 + netherrack: + price: 0.5 + sell-price-difference: 10 + max-buy: 256 + max-sell: 1024 + volatility: 0.55 + white_wool: + price: 6 + max-buy: 64 + max-sell: 100 + oak_log: + price: 8 + max-buy: 100 + max-sell: 200 + volatility: 0.35 + oak_planks: + price: 1.85 + max-buy: 256 + max-sell: 512 + volatility: 0.35 + birch_log: + price: 9 + max-buy: 90 + max-sell: 200 + birch_planks: + price: 2 + max-buy: 256 + max-sell: 512 + spruce_log: + price: 9 + max-buy: 90 + max-sell: 200 + spruce_planks: + price: 2 + max-buy: 256 + max-sell: 512 + jungle_log: + price: 10 + max-buy: 75 + max-sell: 150 + jungle_planks: + price: 2.15 + max-buy: 200 + max-sell: 400 + acacia_log: + price: 9 + max-buy: 90 + max-sell: 200 + acacia_planks: + price: 2 + max-buy: 256 + max-sell: 512 + dark_oak_log: + price: 7.5 + max-buy: 128 + max-sell: 256 + dark_oak_planks: + price: 1.75 + max-buy: 256 + max-sell: 512 + andesite: + price: 1.5 + max-buy: 128 + max-sell: 256 + diorite: + price: 1.5 + max-buy: 128 + max-sell: 256 + granite: + price: 1.5 + max-buy: 128 + max-sell: 256 + soul_sand: + price: 2.7 + max-buy: 128 + max-sell: 256 + terracotta: + price: 3 + max-buy: 128 + max-sell: 256 + white_terracotta: + price: 3.4 + max-buy: 100 + max-sell: 200 + prismarine: + price: 4 + max-buy: 64 + max-sell: 128 + prismarine_bricks: + price: 4.5 + max-buy: 500 + max-sell: 110 + dark_prismarine: + price: 5.5 + max-buy: 45 + max-sell: 100 + sea_lantern: + price: 19 + max-buy: 10 + max-sell: 25 + magma_block: + price: 2.25 + max-buy: 128 + max-sell: 256 + food: + carrot: + price: 3.75 + max-buy: 80 + max-sell: 256 + melon_slice: + price: 1.6 + max-buy: 100 + max-sell: 250 + potato: + price: 2.25 + max-buy: 90 + max-sell: 150 + apple: + price: 4 + max-buy: 64 + max-sell: 100 + collect-first: none + cooked_beef: + price: 5.75 + max-buy: 32 + max-sell: 100 + cooked_porkchop: + price: 5.7 + max-buy: 32 + max-sell: 100 + cooked_chicken: + price: 5.5 + max-buy: 35 + max-sell: 110 + cooked_rabbit: + price: 6 + max-buy: 32 + max-sell: 90 + cooked_mutton: + price: 5.55 + max-buy: 32 + max-sell: 100 + cooked_cod: + price: 6.5 + max-buy: 25 + max-sell: 75 + cooked_salmon: + price: 6.75 + max-buy: 24 + max-sell: 64 + farming: + cactus: + price: 3 + max-buy: 64 + max-sell: 200 + vine: + price: 1.9 + max-buy: 64 + max-sell: 256 + wheat: + price: 2 + max-buy: 128 + max-sell: 256 + sugar_cane: + price: 1.3 + max-buy: 175 + max-sell: 350 + pumpkin: + price: 7.5 + max-buy: 64 + max-sell: 128 + wheat_seeds: + price: 0.85 + max-buy: 128 + max-sell: 200 + collect-first: none + nether_wart: + price: 4.5 + max-buy: 64 + max-sell: 200 + oak_sapling: + price: 2.75 + max-buy: 32 + max-sell: 64 -## See the wiki for info on each setting: https://github.com/Unprotesting/Auto-Tune/wiki + tools: + wooden_pickaxe: + price: 5 + sell-price-difference: 35 + max-buy: 4 + max-sell: 8 + wooden_axe: + price: 7.5 + sell-price-difference: 35 + max-buy: 4 + max-sell: 8 + wooden_sword: + price: 6 + sell-price-difference: 35 + max-buy: 4 + max-sell: 8 + wooden_shovel: + price: 4 + sell-price-difference: 35 + max-buy: 4 + max-sell: 8 + wooden_hoe: + price: 4.5 + sell-price-difference: 35 + max-buy: 4 + max-sell: 8 + stone_pickaxe: + price: 11 + sell-price-difference: 35 + max-buy: 4 + max-sell: 8 + stone_axe: + price: 10.5 + sell-price-difference: 35 + max-buy: 4 + max-sell: 8 + stone_sword: + price: 8.5 + sell-price-difference: 35 + max-buy: 4 + max-sell: 8 + stone_shovel: + price: 5.5 + sell-price-difference: 35 + max-buy: 4 + max-sell: 8 + stone_hoe: + price: 7.5 + sell-price-difference: 35 + max-buy: 4 + max-sell: 8 + golden_pickaxe: + price: 15.0 + sell-price-difference: 35 + max-buy: 3 + max-sell: 8 + golden_axe: + price: 14.5 + sell-price-difference: 35 + max-buy: 3 + max-sell: 8 + golden_sword: + price: 13.0 + sell-price-difference: 35 + max-buy: 3 + max-sell: 8 + golden_shovel: + price: 9.0 + sell-price-difference: 35 + max-buy: 3 + max-sell: 8 + golden_hoe: + price: 10 + sell-price-difference: 35 + max-buy: 3 + max-sell: 8 + fishing_rod: + price: 20 + max-buy: 3 + max-sell: 5 + bow: + price: 25 + max-buy: 3 + max-sell: 5 + enchantments: + protection: + price: 350 + sell-price-difference: 40 + max-buy: 2 + max-sell: 5 + collect-first: player + update-rate: 3 + fire_protection: + price: 400 + sell-price-difference: 40 + max-buy: 2 + max-sell: 5 + collect-first: player + update-rate: 3 + feather_falling: + price: 500 + sell-price-difference: 40 + max-buy: 2 + max-sell: 5 + collect-first: player + update-rate: 3 + blast_protection: + price: 400 + sell-price-difference: 40 + max-buy: 2 + max-sell: 5 + collect-first: player + update-rate: 3 + projectile_protection: + price: 400 + sell-price-difference: 40 + max-buy: 2 + max-sell: 5 + collect-first: player + update-rate: 3 + respiration: + price: 500 + sell-price-difference: 40 + max-buy: 2 + max-sell: 4 + collect-first: player + update-rate: 3 + aqua_affinity: + price: 500 + sell-price-difference: 40 + max-buy: 2 + max-sell: 4 + collect-first: player + update-rate: 3 + thorns: + price: 800 + sell-price-difference: 40 + max-buy: 2 + max-sell: 3 + collect-first: player + update-rate: 5 + sharpness: + price: 450 + sell-price-difference: 40 + max-buy: 3 + max-sell: 5 + collect-first: player + update-rate: 3 + smite: + price: 500 + sell-price-difference: 40 + max-buy: 3 + max-sell: 5 + collect-first: player + update-rate: 3 + bane_of_arthropods: + price: 500 + sell-price-difference: 40 + max-buy: 3 + max-sell: 5 + collect-first: player + update-rate: 3 + looting: + price: 750 + sell-price-difference: 40 + max-buy: 2 + max-sell: 4 + collect-first: player + update-rate: 4 + unbreaking: + price: 600 + sell-price-difference: 40 + max-buy: 3 + max-sell: 5 + collect-first: player + update-rate: 3 + efficiency: + price: 450 + sell-price-difference: 40 + max-buy: 4 + max-sell: 6 + collect-first: player + update-rate: 3 + silk_touch: + price: 1000 + sell-price-difference: 40 + max-buy: 1 + max-sell: 2 + collect-first: player + update-rate: 5 + fortune: + price: 950 + sell-price-difference: 40 + max-buy: 1 + max-sell: 3 + collect-first: player + update-rate: 4 + power: + price: 650 + sell-price-difference: 40 + max-buy: 3 + max-sell: 5 + collect-first: player + update-rate: 3 + punch: + price: 700 + sell-price-difference: 40 + max-buy: 3 + max-sell: 4 + collect-first: player + update-rate: 3 + flame: + price: 750 + sell-price-difference: 40 + max-buy: 2 + max-sell: 4 + collect-first: player + update-rate: 3 + infinity: + price: 1250 + sell-price-difference: 40 + max-buy: 1 + max-sell: 2 + collect-first: player + update-rate: 5 + luck_of_the_sea: + price: 400 + sell-price-difference: 40 + max-buy: 3 + max-sell: 6 + collect-first: player + update-rate: 3 + mending: + price: 2000 + sell-price-difference: 40 + max-buy: 1 + max-sell: 1 + collect-first: player + update-rate: 6 + depth_strider: + price: 600 + sell-price-difference: 40 + max-buy: 2 + max-sell: 4 + collect-first: player + update-rate: 3 + frost_walker: + price: 750 + sell-price-difference: 40 + max-buy: 2 + max-sell: 4 + collect-first: player + update-rate: 4 + soul_speed: + price: 725 + sell-price-difference: 40 + max-buy: 2 + max-sell: 4 + collect-first: player + update-rate: 4 + fire_aspect: + price: 650 + sell-price-difference: 40 + max-buy: 3 + max-sell: 5 + collect-first: player + update-rate: 3 + impaling: + price: 775 + sell-price-difference: 40 + max-buy: 2 + max-sell: 5 + collect-first: player + update-rate: 4 + knockback: + price: 650 + sell-price-difference: 40 + max-buy: 3 + max-sell: 6 + collect-first: player + update-rate: 3 + sweeping: + price: 800 + sell-price-difference: 40 + max-buy: 2 + max-sell: 4 + collect-first: player + update-rate: 5 + channeling: + price: 800 + sell-price-difference: 40 + max-buy: 2 + max-sell: 4 + collect-first: player + update-rate: 5 + loyalty: + price: 750 + sell-price-difference: 40 + max-buy: 2 + max-sell: 4 + collect-first: player + update-rate: 5 + riptide: + price: 800 + sell-price-difference: 40 + max-buy: 2 + max-sell: 4 + collect-first: player + update-rate: 5 + multishot: + price: 650 + sell-price-difference: 40 + max-buy: 3 + max-sell: 6 + collect-first: player + update-rate: 4 + piercing: + price: 600 + sell-price-difference: 40 + max-buy: 3 + max-sell: 6 + collect-first: player + update-rate: 3 + quick_charge: + price: 650 + sell-price-difference: 40 + max-buy: 3 + max-sell: 6 + collect-first: player + update-rate: 3 + lure: + price: 500 + sell-price-difference: 40 + max-buy: 4 + max-sell: 8 + collect-first: player + update-rate: 3 + other: + flint: + price: 4 + max-buy: 64 + max-sell: 128 + gunpowder: + price: 17.5 + max-buy: 64 + max-sell: 100 + leather: + price: 15.5 + max-buy: 64 + max-sell: 100 + ink_sac: + price: 2.5 + max-buy: 32 + max-sell: 45 + feather: + price: 3.75 + max-buy: 32 + max-sell: 64 + bone: + price: 6.5 + max-buy: 64 + max-sell: 128 + string: + price: 4.5 + max-buy: 64 + max-sell: 128 + rotten_flesh: + price: 0.35 + sell-price-difference: 10 + max-buy: 200 + max-sell: 450 + volatility: 0.45 + collect-first: none + spider_eye: + price: 7.5 + max-buy: 64 + max-sell: 128 + slime_ball: + price: 55 + sell-price-difference: 25 + max-buy: 32 + max-sell: 64 + collect-first: player + ender_pearl: + price: 65 + sell-price-difference: 25 + max-buy: 8 + max-sell: 32 + collect-first: player + nether_star: + price: 10000 + sell-price-difference: 40 + max-buy: 1 + max-sell: 1 + volatility: 0.2 + update-rate: 10 + collect-first-setting: player + blaze_rod: + price: 95 + sell-price-difference: 27.5 + max-buy: 6 + max-sell: 16 + collect-first-setting: player + update-rate: 2 + arrow: + price: 1.45 + max-buy: 100 + max-sell: 200 + stick: + price: 0.75 + max-buy: 64 + max_sell: 128 + book: + price: 22.5 + sell-price-difference: 25 + max-buy: 20 + max-sell: 32 -## Shop sections configuration -sections: - 'Natural Resources': - ## Block that the section image is displayed as - block: 'IRON_ORE' - ## Background for sub-menu - ## Use 'NONE' for no background - background: 'GRAY_STAINED_GLASS_PANE' - ## Position in Main Menu GUI - position: 10 - ## Optional - set to disabled to disable the back button when running "/shop ". - ## This wont disable the back button when running just "/shop" - back-menu-button-enabled: true - ## Set the display name for the section - display-name: '&6Natural Resources' - 'Blocks': - block: 'STONE' - position: 12 - background: 'GRAY_STAINED_GLASS_PANE' - back-menu-button-enabled: true - display-name: '&6Blocks' - 'Food': - block: 'COOKED_BEEF' - position: 14 - background: 'GRAY_STAINED_GLASS_PANE' - back-menu-button-enabled: true - display-name: '&6Food' - 'Farming': - block: 'OAK_SAPLING' - position: 16 - background: 'GRAY_STAINED_GLASS_PANE' - back-menu-button-enabled: true - display-name: '&6Farming' - 'Tools': - block: 'DIAMOND_PICKAXE' - position: 20 - background: 'GRAY_STAINED_GLASS_PANE' - back-menu-button-enabled: true - display-name: '&6Tools' - 'Other': - block: 'STICK' - position: 24 - background: 'GRAY_STAINED_GLASS_PANE' - back-menu-button-enabled: true - display-name: '&6Other' -## Set the default / starting prices for the items you want available in the shop. -## IMPORTANT: Thee prices of these items can't be changed once the database has been created. -## IMPORTANT: To change the price of items use /at price or reset the data.db file. -## Info: Material names are available here: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html. -## IMPORTANT: Material names are case sensitive! (All caps and underscores) -## Options: 'price: ' set the default starting price of the item. -## Options: 'section: ' set the section of this item. -## Options: 'locked: ' set the price to be locked or variable (variable by default). -## Options: 'sell-difference: ' set a custom sell-price-difference (default set in config). -## Options: 'max-buy': set a maximum quantity that can be purchased in a time-period. -## Options: 'max-sell': set a maximum quantity that can be sold in a time-period. -## Options: 'max-volatility: ' set the maximum volatility per time-period for this individual item. -## Options: 'min-volatility: ' set the minimum volatility per time-period for this individual item. -## Options: 'display-name': ' set the display name of the item. -## Options: 'collect-first-setting': ' ('NONE'|'SERVER_WIDE'|'EACH_PLAYER') whether the item needs to be collected before it can be purchased. - ## Example: - ## GRASS_BLOCK: - ## price: 50.00 - ## section: 'Blocks' This item will exist within the 'Blocks' shop-section - ## locked: true <- Example of a locked item - ## sell-difference: 0.0 <- Example of a set sell-difference item - ## max-buy: 10 <- Only 10 items can be bought each time-period - you can increase this on large servers - ## max-sell: 12 <- Only 12 items can be sold each time-period - you can increase this on large servers - ## max-volatility: 0.25 <- Example of an item with a lower max-volatility - ## min-volatility: 0.05 <- Example of an item with a higher min-volatility - ## display-name: '&aGrass' <- Example of a custom display name (with a green color code) - ## collect-first-setting: 'EACH_PLAYER' <- Example of a custom collect-first-setting - -shops: - COAL: - price: 15.00 - max-buy: 80 - max-sell: 115 - section: 'Natural Resources' - IRON_INGOT: - price: 17.00 - max-buy: 75 - max-sell: 100 - section: 'Natural Resources' - COPPER_INGOT: - price: 20.00 - max-buy: 64 - max-sell: 80 - section: 'Natural Resources' - GOLD_INGOT: - price: 25.00 - max-buy: 45 - max-sell: 75 - section: 'Natural Resources' - DIAMOND: - price: 325.00 - max-buy: 15 - max-sell: 32 - section: 'Natural Resources' - collect-first-setting: 'SERVER_WIDE' - AMETHYST_SHARD: - price: 22.00 - max-buy: 32 - max-sell: 45 - section: 'Natural Resources' - LAPIS_LAZULI: - price: 12.00 - max-buy: 128 - max-sell: 256 - section: 'Natural Resources' - EMERALD: - price: 145.00 - max-buy: 12 - max-sell: 32 - section: 'Natural Resources' - collect-first-setting: 'SERVER_WIDE' - QUARTZ: - price: 11.00 - max-buy: 40 - max-sell: 125 - section: 'Natural Resources' - REDSTONE: - price: 8.00 - max-buy: 80 - max-sell: 128 - section: 'Natural Resources' - NETHERITE_INGOT: - price: 7500.00 - max-buy: 1 - max-sell: 2 - section: 'Natural Resources' - collect-first-setting: 'EACH_PLAYER' - GLOWSTONE_DUST: - price: 4.00 - max-buy: 128 - max-sell: 256 - section: 'Natural Resources' - DIRT: - price: 0.5 - max-buy: 512 - max-sell: 1024 - section: 'Blocks' - COBBLESTONE: - price: 1.00 - max-buy: 256 - max-sell: 800 - section: 'Blocks' - STONE: - price: 2.00 - max-buy: 128 - max-sell: 256 - section: 'Blocks' - GRAVEL: - price: 3.00 - max-buy: 128 - max-sell: 256 - section: 'Blocks' - SAND: - price: 1.00 - max-buy: 128 - max-sell: 500 - section: 'Blocks' - SANDSTONE: - price: 4.00 - max-buy: 100 - max-sell: 250 - section: 'Blocks' - OBSIDIAN: - price: 15.00 - max-buy: 20 - max-sell: 64 - section: 'Blocks' - collect-first-setting: 'SERVER_WIDE' - END_STONE: - price: 3.50 - max-buy: 80 - max-sell: 200 - section: 'Blocks' - collect-first-setting: 'SERVER_WIDE' - NETHERRACK: - price: 1.00 - max-buy: 256 - max-sell: 1024 - section: 'Blocks' - WHITE_WOOL: - price: 6.50 - max-buy: 64 - max-sell: 80 - section: 'Blocks' - OAK_LOG: - price: 8.00 - max-buy: 90 - max-sell: 256 - section: 'Blocks' - MOSS_BLOCK: - price: 35.00 - max-buy: 15 - max-sell: 32 - section: 'Blocks' - CACTUS: - price: 3.00 - max-buy: 64 - max-sell: 200 - section: 'Farming' - VINE: - price: 2.00 - max-buy: 64 - max-sell: 256 - section: 'Farming' - CARROT: - price: 4.00 - max-buy: 80 - max-sell: 256 - section: 'Food' - MELON_SLICE: - price: 1.75 - max-buy: 85 - max-sell: 175 - section: 'Food' - POTATO: - price: 2.25 - max-buy: 80 - max-sell: 120 - section: 'Food' - APPLE: - price: 4.00 - max-buy: 64 - max-sell: 100 - section: 'Food' - WHEAT: - price: 2.00 - max-buy: 128 - max-sell: 256 - section: 'Farming' - SUGAR_CANE: - price: 1.50 - max-buy: 164 - max-sell: 256 - section: 'Farming' - BEEF: - price: 2.50 - max-buy: 64 - max-sell: 150 - section: 'Food' - PORKCHOP: - price: 2.25 - max-buy: 64 - max-sell: 150 - section: 'Food' - CHICKEN: - price: 1.45 - max-buy: 64 - max-sell: 150 - section: 'Food' - RABBIT: - price: 2.50 - max-buy: 64 - max-sell: 150 - section: 'Food' - MUTTON: - price: 2.00 - max-buy: 64 - max-sell: 150 - section: 'Food' - PUMPKIN: - price: 8.00 - max-buy: 64 - max-sell: 128 - section: 'Farming' - COD: - price: 6.00 - max-buy: 96 - max-sell: 124 - section: 'Food' - WHEAT_SEEDS: - price: 1.25 - max-buy: 80 - max-sell: 200 - section: 'Farming' - NETHER_WART: - price: 4.00 - max-buy: 64 - max-sell: 200 - section: 'Farming' - collect-first-setting: 'SERVER_WIDE' - FLINT: - price: 4.00 - max-buy: 64 - max-sell: 128 - section: 'Other' - GUNPOWDER: - price: 12.50 - max-buy: 64 - max-sell: 128 - section: 'Other' - LEATHER: - price: 20.00 - max-buy: 64 - max-sell: 128 - section: 'Other' - INK_SAC: - price: 2.50 - max-buy: 32 - max-sell: 64 - section: 'Other' - FEATHER: - price: 4.00 - max-buy: 32 - max-sell: 64 - section: 'Other' - BONE: - price: 6.00 - max-buy: 64 - max-sell: 100 - section: 'Other' - STRING: - price: 4.00 - max-buy: 64 - max-sell: 100 - section: 'Other' - ROTTEN_FLESH: - price: 0.50 - max-buy: 64 - max-sell: 128 - section: 'Food' - SPIDER_EYE: - price: 7.00 - max-buy: 64 - max-sell: 128 - section: 'Other' - SLIME_BALL: - price: 25.00 - max-buy: 32 - max-sell: 64 - section: 'Other' - ENDER_PEARL: - price: 45.00 - max-buy: 8 - max-sell: 20 - section: 'Other' - collect-first-setting: 'SERVER_WIDE' - NETHER_STAR: - price: 10000.00 - max-buy: 1 - max-sell: 1 - section: 'Other' - collect-first-setting: 'EACH_PLAYER' - BLAZE_ROD: - price: 85.00 - max-buy: 6 - max-sell: 15 - section: 'Other' - collect-first-setting: 'SERVER_WIDE' - ARROW: - price: 2.00 - max-buy: 64 - max-sell: 128 - section: 'Other' - OAK_PLANKS: - price: 0.5 - max-buy: 128 - max-sell: 256 - section: 'Blocks' - BIRCH_PLANKS: - price: 0.5 - max-buy: 128 - max-sell: 256 - section: 'Blocks' - SPRUCE_PLANKS: - price: 0.5 - max-buy: 128 - max-sell: 256 - section: 'Blocks' - JUNGLE_PLANKS: - price: 0.5 - max-buy: 128 - max-sell: 256 - section: 'Blocks' - DARK_OAK_PLANKS: - price: 0.5 - max-buy: 128 - max-sell: 256 - section: 'Blocks' - ACACIA_PLANKS: - price: 0.5 - max-buy: 128 - max-sell: 256 - section: 'Blocks' - OAK_SAPLING: - price: 2.5 - max-buy: 32 - max-sell: 64 - section: 'Farming' - STICK: - price: 0.2 - max-buy: 64 - max-sell: 128 - section: 'Other' - BOOK: - price: 22.0 - max-buy: 20 - max-sell: 32 - section: 'Other' - WOODEN_PICKAXE: - price: 8.0 - max-buy: 4 - max-sell: 8 - section: 'Tools' - WOODEN_AXE: - price: 7.5 - max-buy: 4 - max-sell: 8 - section: 'Tools' - WOODEN_SWORD: - price: 6.5 - max-buy: 4 - max-sell: 8 - section: 'Tools' - WOODEN_SHOVEL: - price: 3.5 - max-buy: 4 - max-sell: 8 - section: 'Tools' - WOODEN_HOE: - price: 3.5 - max-buy: 4 - max-sell: 8 - section: 'Tools' - STONE_PICKAXE: - price: 11.0 - max-buy: 4 - max-sell: 8 - section: 'Tools' - STONE_AXE: - price: 10.5 - max-buy: 4 - max-sell: 8 - section: 'Tools' - STONE_SWORD: - price: 9.0 - max-buy: 4 - max-sell: 8 - section: 'Tools' - STONE_SHOVEL: - price: 5.0 - max-buy: 4 - max-sell: 8 - section: 'Tools' - STONE_HOE: - price: 5.0 - max-buy: 4 - max-sell: 8 - section: 'Tools' - GOLDEN_PICKAXE: - price: 12.0 - max-buy: 3 - max-sell: 8 - section: 'Tools' - GOLDEN_AXE: - price: 11.5 - max-buy: 3 - max-sell: 8 - section: 'Tools' - GOLDEN_SWORD: - price: 10.0 - max-buy: 3 - max-sell: 8 - section: 'Tools' - GOLDEN_SHOVEL: - price: 6.0 - max-buy: 3 - max-sell: 8 - section: 'Tools' - GOLDEN_HOE: - price: 6.0 - max-buy: 3 - max-sell: 8 - section: 'Tools' - IRON_PICKAXE: - price: 18.0 - max-buy: 3 - max-sell: 6 - section: 'Tools' - IRON_AXE: - price: 17.5 - max-buy: 3 - max-sell: 6 - section: 'Tools' - IRON_SWORD: - price: 13.0 - max-buy: 3 - max-sell: 6 - section: 'Tools' - IRON_SHOVEL: - price: 7.0 - max-buy: 3 - max-sell: 6 - section: 'Tools' - IRON_HOE: - price: 7.0 - max-buy: 3 - max-sell: 6 - section: 'Tools' - DIAMOND_PICKAXE: - price: 260.0 - max-buy: 2 - max-sell: 3 - section: 'Tools' - collect-first-setting: 'SERVER_WIDE' - DIAMOND_AXE: - price: 250.0 - max-buy: 2 - max-sell: 3 - section: 'Tools' - collect-first-setting: 'SERVER_WIDE' - DIAMOND_SWORD: - price: 180.0 - max-buy: 2 - max-sell: 3 - section: 'Tools' - collect-first-setting: 'SERVER_WIDE' - DIAMOND_SHOVEL: - price: 110.0 - max-buy: 2 - max-sell: 3 - section: 'Tools' - collect-first-setting: 'SERVER_WIDE' - DIAMOND_HOE: - price: 110.0 - max-buy: 2 - max-sell: 3 - section: 'Tools' - collect-first-setting: 'SERVER_WIDE' - LEATHER_HELMET: - price: 22.50 - max-buy: 2 - max-sell: 4 - section: 'Tools' - LEATHER_CHESTPLATE: - price: 46.00 - max-buy: 2 - max-sell: 3 - section: 'Tools' - LEATHER_LEGGINGS: - price: 25.50 - max-buy: 2 - max-sell: 3 - section: 'Tools' - LEATHER_BOOTS: - price: 20.00 - max-buy: 2 - max-sell: 4 - section: 'Tools' - IRON_HELMET: - price: 45.50 - max-buy: 2 - max-sell: 4 - section: 'Tools' - IRON_CHESTPLATE: - price: 86.00 - max-buy: 2 - max-sell: 3 - section: 'Tools' - IRON_LEGGINGS: - price: 65.50 - max-buy: 2 - max-sell: 3 - section: 'Tools' - IRON_BOOTS: - price: 38.00 - max-buy: 2 - max-sell: 4 - section: 'Tools' - GOLDEN_HELMET: - price: 40.50 - max-buy: 2 - max-sell: 4 - section: 'Tools' - GOLDEN_CHESTPLATE: - price: 80.00 - max-buy: 2 - max-sell: 3 - section: 'Tools' - GOLDEN_LEGGINGS: - price: 60.50 - max-buy: 2 - max-sell: 3 - section: 'Tools' - GOLDEN_BOOTS: - price: 30.00 - max-buy: 2 - max-sell: 4 - section: 'Tools' - DIAMOND_HELMET: - price: 425.50 - max-buy: 2 - max-sell: 4 - section: 'Tools' - collect-first-setting: 'SERVER_WIDE' - DIAMOND_CHESTPLATE: - price: 900.00 - max-buy: 2 - max-sell: 3 - section: 'Tools' - collect-first-setting: 'SERVER_WIDE' - DIAMOND_LEGGINGS: - price: 620.50 - max-buy: 2 - max-sell: 3 - section: 'Tools' - collect-first-setting: 'SERVER_WIDE' - DIAMOND_BOOTS: - price: 350.00 - max-buy: 2 - max-sell: 4 - section: 'Tools' - collect-first-setting: 'SERVER_WIDE' - FISHING_ROD: - price: 25.00 - max-buy: 3 - max-sell: 4 - section: 'Tools' - BOW: - price: 28.00 - max-buy: 3 - max-sell: 4 - section: 'Tools' \ No newline at end of file diff --git a/src/main/resources/web/favicon.ico b/src/main/resources/web/favicon.ico deleted file mode 100644 index 48f6ebc..0000000 Binary files a/src/main/resources/web/favicon.ico and /dev/null differ diff --git a/src/main/resources/web/trade.html b/src/main/resources/web/trade.html deleted file mode 100644 index c1ac6a9..0000000 --- a/src/main/resources/web/trade.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - diff --git a/src/test/java/unprotesting/com/github/AutoTuneTest.java b/src/test/java/unprotesting/com/github/AutoTuneTest.java deleted file mode 100644 index 8ec6209..0000000 --- a/src/test/java/unprotesting/com/github/AutoTuneTest.java +++ /dev/null @@ -1,98 +0,0 @@ -package unprotesting.com.github; - -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.io.File; -import java.util.ArrayList; -import java.util.List; - -import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.MethodOrderer; -import org.junit.jupiter.api.Order; -import org.junit.jupiter.api.RepeatedTest; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.TestMethodOrder; - -import unprotesting.com.github.data.persistent.Database; -import unprotesting.com.github.data.persistent.TimePeriod; - -@TestMethodOrder(MethodOrderer.OrderAnnotation.class) -@DisplayName("Auto-Tune Tests") -class AutoTuneTest { - - private long startTime; - private static Database db; - private static List times = new ArrayList<>(); - - @BeforeAll - static void beforeAll() { - File file = new File("./tests/"); - file.mkdirs(); - db = new Database("./tests/"); - db.getMap().clear(); - - } - - - @AfterAll - static void afterAll() { - - db.getDb().close(); - File testFolder = new File("./tests/"); - testFolder.delete(); - - long total = 0; - for (Long time : times) { - total += time; - } - total /= times.size(); - System.out.println("Average Test Duration: " + total + " nanoseconds or " - + total / 1000000 + " milliseconds or " + total / 1000000000 + " seconds."); - - } - - @BeforeEach - void beforeEach() { - - db.getMap().clear(); - startTime = System.nanoTime(); - - } - - @AfterEach - void afterEach() { - - long endTime = System.nanoTime(); - assertTrue(db.getMap().size() == 100); - long duration = (endTime - startTime); - - System.out.println("Test Duration: " + duration + " nanoseconds or " - + duration / 1000000 + " milliseconds or " + duration / 1000000000 + " seconds."); - times.add(duration); - - } - - @Test - @Order(1) - @DisplayName("Data entry test") - @RepeatedTest(2) - void firstTest() { - - System.out.println("Testing 100 empty data inputs."); - - for (int i = 0; i < 100; i++) { - - TimePeriod tp = new TimePeriod(true); - db.getMap().put(db.getMap().size(), tp); - - } - - System.out.println(db.getMap().size()); - - } - -}