├── Jenkinsfile ├── LICENSE.md ├── README.md ├── pom.xml ├── screenshots └── cover.png └── src └── main ├── java └── ua │ └── leonidius │ └── trdinterface │ ├── ItemName.java │ ├── Message.java │ ├── Settings.java │ ├── ShopCommand.java │ ├── Trading.java │ ├── controllers │ ├── AddEnchantmentController.java │ ├── AmountSelectorController.java │ ├── BaseController.java │ ├── DeleteEnchantmentController.java │ ├── DeleteItemController.java │ ├── EditItemController.java │ ├── InfoController.java │ ├── ItemDetailsEditController.java │ ├── ItemDetailsViewController.java │ ├── ListController.java │ ├── MainController.java │ ├── ManageEnchantmentsController.java │ ├── ModalController.java │ ├── NamingController.java │ ├── buy │ │ ├── categories │ │ │ ├── CategoriesListController.java │ │ │ └── edit │ │ │ │ ├── AddCategoryController.java │ │ │ │ ├── DeleteCategoryController.java │ │ │ │ └── RenameCategoryController.java │ │ └── items │ │ │ ├── BuyAmountSelectorController.java │ │ │ ├── BuyableItemsListController.java │ │ │ ├── discounts │ │ │ ├── AddDiscountController.java │ │ │ └── RemoveDiscountController.java │ │ │ └── edit │ │ │ ├── AddBuyableItemController.java │ │ │ └── ManageBuyableItemController.java │ ├── sell │ │ ├── SellAmountSelectorController.java │ │ ├── SellableItemsListController.java │ │ └── edit │ │ │ ├── AddSellableItemController.java │ │ │ ├── EditSellableItemsController.java │ │ │ └── ManageSellableItemController.java │ └── translations │ │ ├── AddTranslationController.java │ │ ├── DeleteTranslationController.java │ │ ├── EditTranslationController.java │ │ ├── TranslationMenuController.java │ │ └── TranslationsListController.java │ ├── models │ ├── BuyableItem.java │ ├── Category.java │ ├── Discount.java │ ├── SellableItem.java │ ├── Shop.java │ ├── ShopItem.java │ └── Translation.java │ ├── utils │ ├── EnchantmentWrapper.java │ ├── ItemCompare.java │ ├── TimeUnit.java │ └── YamlToDbConverter.java │ └── views │ ├── ScreenManager.java │ ├── elements │ └── CallbackButton.java │ └── screens │ ├── AmountSelectorScreen.java │ ├── CustomScreen.java │ ├── InfoScreen.java │ ├── ItemDetailsEditScreen.java │ ├── ListScreen.java │ ├── MainScreen.java │ ├── ModalScreen.java │ ├── NamingScreen.java │ ├── Screen.java │ ├── SimpleScreen.java │ ├── buy │ └── items │ │ └── edit │ │ ├── AddDiscountScreen.java │ │ ├── ManageBuyableItemScreen.java │ │ └── enchantment │ │ └── AddEnchantmentScreen.java │ ├── sell │ └── edit │ │ └── ManageSellableItemScreen.java │ └── translations │ ├── AddTranslationScreen.java │ └── CustomNameMenuScreen.java └── resources ├── config.yml ├── lang ├── chs.lng ├── cht.lng ├── rus.lng └── ukr.lng └── plugin.yml /Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent { 3 | docker { 4 | image 'maven:3-alpine' 5 | args '-v /root/.m2:/root/.m2' 6 | } 7 | } 8 | stages { 9 | stage('Build') { 10 | steps { 11 | sh 'mvn -B -DskipTests clean package' 12 | } 13 | post { 14 | success { 15 | archiveArtifacts artifacts: 'target/*.jar', fingerprint: true 16 | } 17 | } 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Leonidius20 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Trading Interface 2 | ![cover](screenshots/cover.png) 3 | 4 | Shop system with a graphical interface for [NukkitX][nukkitx] server software for Minecraft Bedrock Edition! 5 | 6 | ## Features: 7 | - Buying and selling items & shop management through an intuitive interface; 8 | - Support for items with enchantments, custom names & lores; 9 | - The list of items, available for buying, is divided into categories for convenience; 10 | - Temporary discounts for items (which expire after a set time); 11 | - Custom translations of items' names (for displaying in the shop). 12 | 13 | ## Installation: 14 | - Make sure that [EconomyAPI][economy] and [DbLib][dblib] are installed on your server; 15 | - Place the plugin's _.jar_ file into _plugins_ folder on your server; 16 | - Launch the server and set up the plugin through its interface. 17 | 18 | ## Setting up: 19 | Shop management functions are available for players with `shop.edit` permission (operators have it by default). Players with this permission will see management buttons in the interface. 20 | 21 | ## Usage: 22 | To open up the shop's interface type `/shop` into the chat. 23 | 24 | ## Translations 25 | If the plugin is not translated into the language of your choosing, a file called `.lng`, where `` is the three-letter ID of your language, will be created in the plugin's data folder. It will contain text strings in the format of `key: value`, where `key` is the string's identifier and `value` is the string itself. Replace values in English with the values in your language, and these new strings will be used by the plugin. You can also start a pull request, placing `.lng` into `src/main/resources/lang`, and your translation may officially become a part of the plugin. 26 | 27 | ## Building from sources 28 | `mvn clean package` 29 | 30 | ## Links 31 | - [Trading Interface on nukkitx.com](https://nukkitx.com/resources/trading-interface.113/) 32 | - [Trading Interface on nukkit.ru](http://forums.voxelwind.com/resources/trading-interface.144/) 33 | 34 | [economy]: https://github.com/EconomyS/EconomyAPI 35 | [dblib]: https://github.com/fromgate/DbLib 36 | [nukkitx]: http://github.com/NukkitX/Nukkit 37 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | ua.leonidius 8 | trdinterface 9 | 2.0.0 10 | jar 11 | Trading Interface 12 | https://github.com/Leonidius20/TradingInterface 13 | 14 | 15 | 16 | UTF-8 17 | 1.8 18 | 1.8 19 | 20 | 21 | 22 | 23 | nukkitx-repo 24 | https://repo.nukkitx.com/snapshot/ 25 | 26 | 27 | onebone 28 | http://jenkins.onebone.me/plugin/repository/everything/ 29 | 30 | 31 | 32 | 33 | 34 | cn.nukkit 35 | nukkit 36 | 1.0-SNAPSHOT 37 | provided 38 | 39 | 40 | me.onebone 41 | economyapi 42 | 1.0.0 43 | provided 44 | 45 | 46 | ru.nukkit.dblib 47 | DbLib 48 | 1.0-SNAPSHOT 49 | provided 50 | 51 | 52 | 53 | 54 | 55 | 56 | src/main/resources 57 | true 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /screenshots/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Leonidius20/TradingInterface/5f97cb39afd54839d819d24cde5bf49775d2561d/screenshots/cover.png -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/ItemName.java: -------------------------------------------------------------------------------- 1 | /*package ua.leonidius.trdinterface; 2 | 3 | import cn.nukkit.item.Item; 4 | 5 | /** 6 | * Created by Leonidius20 on 11.03.17. 7 | */ 8 | /*public class ItemName { 9 | 10 | public static String get (String stringId) { 11 | 12 | if (Trading.customNames.exists(stringId)) { 13 | return Trading.customNames.getString(stringId); 14 | } 15 | 16 | Item item = Item.fromString(stringId); 17 | if (Trading.customNames.exists(item.getId()+"-"+item.getDamage())) { 18 | return Trading.customNames.getString(item.getId() + "-" + item.getDamage()); 19 | } 20 | 21 | int id = item.getId(); 22 | 23 | if (id == 356){ 24 | return "Repeater"; 25 | } else if (id == 125){ 26 | return "Dropper"; 27 | } else if (id == 154){ 28 | return "Hopper"; 29 | }else if (id == 247){ 30 | return "Nether Reactor"; 31 | } else if (id == 395){ 32 | return "Empty map"; 33 | } else if (id == 404){ 34 | return "Comparator"; 35 | } else if (id == 410){ 36 | return "Hopper"; 37 | } else if (id == 420){ 38 | return "Lead"; 39 | } else if (id == 421){ 40 | return "Name Tag"; 41 | } else if (id == 433){ 42 | return "Popped Chorus Fruit"; 43 | } else if (id == 445){ 44 | return "Shulker Shell"; 45 | } else { 46 | return item.getName(); 47 | } 48 | 49 | } 50 | }*/ -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/Message.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface; 2 | 3 | import cn.nukkit.Server; 4 | import cn.nukkit.command.CommandSender; 5 | import cn.nukkit.level.Location; 6 | import cn.nukkit.plugin.PluginBase; 7 | import cn.nukkit.utils.Config; 8 | import cn.nukkit.utils.TextFormat; 9 | 10 | import java.io.File; 11 | import java.io.InputStream; 12 | import java.text.DecimalFormat; 13 | 14 | /** 15 | * Enum for localization. 16 | * The localization logic was initially created by 17 | * fromgate (github.com/fromgate) 18 | * 19 | * @author fromgate, Leonidius20 20 | */ 21 | public enum Message { 22 | 23 | //LNG_LOAD_FAIL("Failed to load languages from file. Default message used"), 24 | LNG_SAVE_FAIL("Failed to save lang file"), 25 | LNG_PRINT_FAIL("Failed to print message to 'null': \"%1%\""), 26 | 27 | // Commands 28 | CMD_CONSOLE("You cannot use this command in console."), 29 | CMD_SHOP("Opens the shop interface"), 30 | 31 | // Main menu 32 | WDW_MAIN_TITLE("Main menu"), 33 | MENU_BUY("Buy items"), 34 | MENU_SELL("Sell items"), 35 | MENU_EDIT_BUY_LIST("Edit buyable items"), 36 | MENU_EDIT_SELL_LIST("Edit sellable items"), 37 | MENU_BROWSE_SELL_LIST("Browse sellable items"), 38 | // EDITED IN 2.0.0 39 | MENU_CUSTOM_NAMES("Custom item translations"), 40 | // end of edited stuff 41 | 42 | // Buttons 43 | BTN_BACK("< Back"), 44 | 45 | // Modal windows 46 | BTN_YES("Yes"), 47 | BTN_NO("No"), 48 | 49 | // Custom names windows (all edited in 2.0.0) 50 | BTN_EDIT_CUSTOM_NAME("* Edit translation"), 51 | BTN_DELETE_CUSTOM_NAME("* Delete translation"), 52 | BTN_ADD_CUSTOM_NAME("+ Add translation"), 53 | 54 | // Success and fail 55 | WDW_SUCCESS_TITLE("Success"), 56 | WDW_FAIL_TITLE("Fail"), 57 | 58 | // Category selector window 59 | WDW_BUY_CAT_TITLE("Choose a category"), 60 | WDW_BUY_NO_CATEGORIES("There are no categories of goods in the shop. In order to use the shop, there must be at least one category."), 61 | 62 | // Buy item selector window 63 | WDW_BUY_EMPTY_CAT("There are no items in this category."), 64 | BTN_ITEM_BUY("%1% (%2%%3%)"), 65 | BTN_ITEM_BUY_SALE("%1% (%2%%3%) &c-%4% pct!"), // edited in 2.0.0 66 | 67 | // Buy window & BuyManageItemScreen 68 | WDW_BUY_TITLE("Buying %1%"), 69 | WDW_BUY_NAME("Name: %1%"), 70 | WDW_BUY_ORIGINAL_NAME("Original name: %1% (%2%)"), // modified in 2.0.0 71 | WDW_BUY_PRICE("Price: %1%%2% per item"), 72 | // edited in 2.0.0 73 | WDW_BUY_DISCOUNT("Discount: %1% percent, time left: %2%"), 74 | WDW_BUY_ORIGINAL_PRICE("Price without discount: %1%%2%"), 75 | // end of edited stuff 76 | WDW_BUY_CUSTOM_LORE("Lore: %1%"), 77 | WDW_BUY_ENCHANTMENTS("Enchantments: %1%"), 78 | WDW_BUY_AMOUNT("Select amount"), 79 | WDW_SELECT_ZERO_TO_RETURN("Select zero to return to the previous screen."), // new in 2.0.0 80 | 81 | // Sell item selector window 82 | WDW_SELL_SELECT_ITEM("Select an item to sell"), 83 | WDW_SELL_NOTHING("You have nothing to sell."), 84 | BTN_ITEM_SELL("%1% (%2%%3%) (x%4%)"), // edited in 2.0.0 85 | WDW_BROWSE_SELLABLE_ITEMS_TITLE("Browsing sellable items"), 86 | WDW_VIEWING_BUYABLE_ITEM("Viewing a buyable item"), 87 | WDW_VIEWING_SELLABLE_ITEM("Viewing a sellable item"), 88 | 89 | // Sell window 90 | WDW_SELL_TITLE("Selling %1%"), 91 | 92 | // EditSellableItems 93 | WDW_EDIT_SELLABLE_ITEMS_EMPTY("There are no sellable items in the shop."), // new in 2.0.0 94 | 95 | // Categories list window 96 | BTN_ADD_CATEGORY("+ Add category"), 97 | 98 | // Category creation window 99 | WDW_NEW_CATEGORY("Creating a new category"), 100 | WDW_NEW_CATEGORY_NAME("Choose a name (leave blank to return):"), 101 | WDW_NEW_CATEGORY_FAIL("A category with such a name already exists."), 102 | WDW_NEW_CATEGORY_SUCCESS("A new category has been created successfully."), 103 | 104 | // Category renaming window 105 | WDW_RENAME_CATEGORY_TITLE("Renaming category"), 106 | WDW_RENAME_CATEGORY_NAME("Choose a new name:"), 107 | 108 | // Category editing window 109 | BTN_RENAME_CATEGORY("* Rename category"), 110 | BTN_DELETE_CATEGORY("* Delete category"), 111 | BTN_ADD_ITEM("+ Add item"), 112 | 113 | // Category deletion window 114 | WDW_DELETE_CATEGORY_TITLE("Deleting category"), 115 | WDW_DELETE_CATEGORY_CONF("Are you sure you want to delete &l%1%&r category? All of the items in this category will be deleted as well. This action cannot be undone."), 116 | 117 | // Adding item windows 118 | WDW_ADD_ITEM_TITLE("Adding item"), 119 | WDW_ADD_ITEM_ID("Item's ID (string or number)"), 120 | WDW_ADD_ITEM_PRICE("Price per item"), 121 | WDW_ADD_ITEM_CUSTOM_NAME("Custom name (optional)"), 122 | WDW_ADD_ITEM_CUSTOM_LORE("Custom lore (optional)"), 123 | WDW_ADD_ITEM_ENCHANTMENTS("You will be able to edit enchantments later."), 124 | WDW_ADD_BUY_ITEM_SUCCESS("You have successfully added &l%1%&r to the list of buyable items."), 125 | WDW_ADD_SELL_ITEM_SUCCESS("You have successfully added &l%1%&r to the list of sellable items."), 126 | WDW_INVALID_PARAMS("Invalid parameters."), 127 | // WDW_ITEM_ALREADY_EXISTS("This item is already on the list."), 128 | // next few are new in 2.0.0 129 | WDW_ADD_ITEM_MISSING_ID("please fill in item's ID."), 130 | WDW_ADD_ITEM_INVALID_ID("the item with such an ID is not registered on the server."), 131 | WDW_ADD_ITEM_INVALID_PRICE("price format is invalid."), 132 | WDW_EDIT_ITEM_NEGATIVE_PRICE("price cannot be negative."), 133 | WDW_ADD_ITEM_INVALID_NBT("failed to write NBT tag."), 134 | 135 | // Item editing windows 136 | WDW_EDIT_ITEM_TITLE("Editing item"), 137 | //BUY_ITEM_INFO ("Item: %1%\nPrice: %2%%3%\nDiscount: %4%%"), 138 | //BUY_ITEM_INFO_DISC ("Item: %1%\nPrice: %2%%3%\nDiscount: %4%%\nPrice with discount: %5%%6%"), 139 | // SELL_ITEM_INFO("Item: %1%\nPrice: %2%%3%"), 140 | BTN_EDIT_ITEM("* Edit item"), 141 | BTN_DELETE_ITEM("* Delete item"), 142 | // BTN_EDIT_DISCOUNT ("* Edit discount"), 143 | BTN_ADD_DISCOUNT("+ Add discount"), 144 | BTN_REMOVE_DISCOUNT("* Remove discount"), // new in 2.0.0 145 | 146 | // AddEnchantmentFailScreen 147 | // WDW_ADD_ENCHANTMENT_FAIL("Failed to add enchantment."), 148 | 149 | // BuyManageItemScreen 150 | BTN_BUY_ITEM("Buy this item"), 151 | BTN_MANAGE_ENCHANTMENTS("Manage enchantments"), 152 | BTN_ADD_ENCHANTMENT("+ Add enchantment"), 153 | // BTN_REMOVE_ENCHANTMENT ("Remove enchantment"), 154 | 155 | // Item deletion windows 156 | WDW_DELETE_ITEM_TITLE("Deleting item"), 157 | WDW_DELETE_BUY_ITEM_CONF("Are you sure you want to delete &l%1%&r from the list of buyable items? This action can't be undone."), // cosmetic change in 2.0.0 158 | WDW_DELETE_SELL_ITEM_CONF("Are you sure you want to delete &l%1%&r from the list of sellable items? This action can't be undone."), // cosmetic change in 2.0.0 159 | 160 | // Discount editing window 161 | // EDITED IN 2.0.0! 162 | WDW_EDIT_DISCOUNT_TITLE("Adding discount"), 163 | WDW_EDIT_DISCOUNT_HINT("Enter discount in percents (0 to return):"), 164 | WDW_EDIT_DISCOUNT_DURATION("Enter discount duration (numerical value):"), 165 | WDW_EDIT_DISCOUNT_MORE_THAN_100("Discount can't be bigger than 100% or less than 0%."), 166 | WDW_REMOVE_DISCOUNT_CONF("Are you sure you want to remove a %1% percent discount from &l%2%&r?"), // added in 2.0.0 167 | // end of edited stuff 168 | 169 | // Custom names list window 170 | WDW_CUSTOM_NAMES_HINT("You can add a custom translation for an item's name. Note! It has nothing to do with custom names (which can be added with an anvil) and only affects the item's name in the shop."), // edited in 2.0.0 171 | WDW_CUSTOM_NAME_TITLE("Item name translation"), 172 | 173 | // Custom name editing menu 174 | WDW_CUSTOM_NAME_INFO("Item's ID: %1%\nOriginal name: %2%\nTranslation: %3%"), 175 | 176 | // Custom name adding window 177 | WDW_ADD_CUSTOM_NAME_TITLE("Adding translation"), // changed in 2.0.0 178 | WDW_ADD_CUSTOM_NAME_FAIL("There is already a custom translation for this item's name."), // changed in 2.0.0 179 | 180 | // Custom name editing window 181 | WDW_EDIT_CUSTOM_NAME_TITLE("Editing translation"), // changed in 2.0.0 182 | WDW_CUSTOM_NAME_HINT("Item's name translation:"), // changed in 2.0.0 183 | 184 | // Custom name deletion window 185 | WDW_DELETE_CUSTOM_NAME_TITLE("Deleting translation"), // changed in 2.0.0 186 | WDW_DELETE_CUSTOM_NAME_CONF("Are you sure you want to delete a custom translation for the item's name? This action can't be undone."), // changed in 2.0.0 187 | 188 | WDW_ADD_ENCHANTMENT_TITLE("Adding an enchantment"), 189 | WDW_ADD_ENCHANTMENT_SELECTOR_HINT("Select an enchantment:"), 190 | WDW_ADD_ENCHANTMENT_LEVEL_HINT("Select a level (0 to return)"), 191 | 192 | // WDW_REMOVE_ENCHANTMENT_HINT ("Select an enchantment to remove:"), 193 | 194 | WDW_MANAGE_ENCHANTMENTS_TITLE("Managing enchantments on %1%"), 195 | WDW_MANAGE_ENCHANTMENTS_TEXT("Select an enchantment from the list to remove it or press \"+ Add enchantment\" to add one."), 196 | WDW_MANAGE_ENCHANTMENTS_EMPTY("There are no enchantments on this item"), 197 | 198 | WDW_REMOVE_ENCHANTMENT_TITLE("Removing an enchantment"), 199 | WDW_REMOVE_ENCHANTMENT_CONF("Are you sure you want to remove &l%1%&r from &l%2%&r?"), 200 | 201 | // Buy success and fail strings 202 | BUY_NO_MONEY("Not enough money to buy this item."), 203 | BUY_NO_SPACE("There is no free space in your inventory."), 204 | BUY_NO_SPACE_AND_MONEY("There is no free space in your inventory and there is not enough money to buy this item."), 205 | ERROR("An error occurred."), 206 | ERROR_DESC("An error occurred: %1%"), 207 | BUY_SUCCESS("You have successfully bought %1%x &l%2%&r for %3%%4%."), 208 | 209 | // Sell success string 210 | SELL_SUCCESS("You have successfully sold %1%x &l%2%&r for %3%%4%."), 211 | 212 | // List edit logs 213 | LOG_CATEGORY_ADDED("User %1% has added a new category of buyable items called %2%."), 214 | LOG_CATEGORY_DELETED("User %1% has deleted a category of buyable items called %2%."), 215 | LOG_CATEGORY_RENAMED("User %1% has renamed a category of buyable items called %2% into %3%."), 216 | 217 | LOG_BUY_ITEM_ADDED("User %1% has added %2% (ID: %3%) to the list of buyable items, price: %4%%5%."), 218 | LOG_BUY_ITEM_ADDED_WITH_CUSTOM_NAME("User %1% has added %2% (original name: %3%, ID: %4%) to the list of buyable items, price: %5%%6%."), 219 | LOG_BUY_ITEM_DELETED("User %1% has deleted %2% (ID: %3%) from the list of buyable items."), 220 | 221 | // the next line was edited in 2.0.0 222 | LOG_BUY_ITEM_EDITED("User %1% has modified the buyable item %2%: %3%."), 223 | 224 | LOG_EDITED_ID("changed ID from %1% to %2%"), 225 | LOG_EDITED_NAME("changed name from %1% to %2%"), 226 | LOG_EDITED_PRICE("changed price from %1%%2% to %3%%2%"), 227 | LOG_EDITED_LORE("changed lore from %1% to %2%"), 228 | LOG_ADDED_LORE("added a lore (%1%)"), 229 | LOG_REMOVED_LORE("removed lore (%1%)"), 230 | LOG_ADDED_CUSTOM_NAME("added a custom name (%1%)"), 231 | LOG_EDITED_CUSTOM_NAME("changed custom name from %1% to %2%"), 232 | LOG_REMOVED_CUSTOM_NAME("removed custom name (%1%)"), 233 | 234 | // LOG_BUY_ITEM_EDITED ("User %1% has changed the price of %2% (ID: %3%) for buying, new price: %4%%5%, old price: %6%%7%."), 235 | 236 | LOG_DISCOUNT_ADDED("User %1% has added a %2%% discount for %3% (ID: %4%) for %5% %6%."), 237 | // LOG_DISCOUNT_EDITED ("User %1% has changed the discount for %2% (ID: %3%), new discount: %4%%, old discount: %5%%."), 238 | LOG_DISCOUNT_DELETED("User %1% has deleted the discount for %2% (ID: %3%)."), 239 | 240 | LOG_SELL_ITEM_ADDED("User %1% has added %2% (ID: %3%) to the list of sellable items, price: %4%%5%."), 241 | LOG_SELL_ITEM_ADDED_WITH_CUSTOM_NAME("User %1% has added %2% (original name: %3%, ID: %4%) to the list of sellable items, price: %5%%6%."), 242 | LOG_SELL_ITEM_DELETED("User %1% has deleted %2% (ID: %3%) from the list of sellable items."), 243 | 244 | // the next line was edited in 2.0.0 245 | LOG_SELL_ITEM_EDITED("User %1% has modified the sellable item %2%: %3%."), 246 | 247 | LOG_BUY_ENCHANTMENT_ADDED("User %1% has added %2% %3% enchantment to a buyable item %4% (%5%)."), 248 | LOG_SELL_ENCHANTMENT_ADDED("User %1% has added %2% %3% enchantment to a sellable item %4% (%5%)."), 249 | LOG_BUY_ENCHANTMENT_REMOVED("User %1% has removed %2% %3% enchantment from a buyable item %4% (%5%)."), 250 | LOG_SELL_ENCHANTMENT_REMOVED("User %1% has removed %2% %3% enchantment from a sellable item %4% (%5%)."), 251 | 252 | // Transaction logs 253 | LOG_BOUGHT("Player %1% have bought %2%x %3% (ID: %4%) for %5%%6%."), // edited 254 | LOG_SOLD("Player %1% have sold %2%x %3% (ID: %4%) for %5%%6%."), // edited 255 | 256 | // edited in 2.0.0 257 | LOG_TRANSLATION_ADDED("Player %1% have added a custom translation for %2% (%3%) - %4%."), 258 | LOG_TRANSLATION_CHANGED("Player %1% have changed a custom translation for %2% (%3%) from %4% to %5%."), 259 | LOG_TRANSLATION_DELETED("Player %1% have deleted a custom translation for %2% (%3%)."), 260 | 261 | // YAML to DB conversion 262 | LOG_BUYABLE_ITEMS_FOUND("Found buyList.yml, importing items to the database..."), 263 | LOG_SELLABLE_ITEMS_FOUND("Found sellList.yml, importing items to the database..."), 264 | LOG_TRANSLATIONS_FOUND("Found customItemNames.yml, importing translations to the database..."), 265 | 266 | LOG_BUYABLE_ITEMS_IMPORTED("Imported %1% categories and %2% buyable items, buyList.yml deleted."), 267 | LOG_SELLABLE_ITEMS_IMPORTED("Imported %1% sellable items, sellList.yml deleted."), 268 | LOG_ALL_TRANSLATIONS_IMPORTED("Imported %1% translations, customItemNames.yml deleted."), 269 | LOG_IMPORT_SKIPPED_TRANSLATIONS("Imported %1% translations, skipped %2% translations for items, for which there are already custom translations. Skipped items are kept in customItemNames.yml."), 270 | 271 | LOG_IMPORT_FAILED("Failed to import."), 272 | 273 | LOG_READING_NBT_FAILED("Error reading NBT tag on item with record_id %1%"), 274 | 275 | // time units 276 | SECONDS("seconds"), 277 | MINUTES("minutes"), 278 | HOURS("hours"), 279 | DAYS("days"), 280 | MONTHS("months"), 281 | INFINITY("infinity"); 282 | 283 | private static String language = "english"; 284 | 285 | private static PluginBase plugin = null; 286 | 287 | public void log(Object... s) { 288 | plugin.getLogger().info(getText(s)); 289 | } 290 | 291 | public void error(Object... params) { 292 | plugin.getLogger().error(getText(params)); 293 | } 294 | 295 | public void print(CommandSender sender, Object... s) { 296 | if (sender == null) { 297 | Message.LNG_PRINT_FAIL.log(this.name()); 298 | return; 299 | } 300 | sender.sendMessage(getText(s)); 301 | } 302 | 303 | /* public boolean broadcast(String permission, Object... s) { 304 | for (Player player : plugin.getServer().getOnlinePlayers().values()) { 305 | if (permission == null || player.hasPermission(permission)) print(player, s); 306 | } 307 | return true; 308 | } */ 309 | 310 | public String getText(Object... keys) { 311 | if (keys.length == 0) return TextFormat.colorize(this.message); 312 | String str = this.message; 313 | boolean fullFloat = false; 314 | int count = 1; 315 | DecimalFormat fmt = new DecimalFormat("####0.##"); 316 | for (Object key : keys) { 317 | String s = key.toString(); 318 | if (s.equals("FULLFLOAT")) { 319 | fullFloat = true; 320 | continue; 321 | } else if (key instanceof Location) { 322 | Location loc = (Location) key; 323 | if (fullFloat) 324 | s = loc.getLevel().getName() + "[" + loc.getX() + ", " + loc.getY() + ", " + loc.getZ() + "]"; 325 | else 326 | s = loc.getLevel().getName() + "[" + fmt.format(loc.getX()) + ", " + fmt.format(loc.getY()) + ", " + fmt.format(loc.getZ()) + "]"; 327 | } else if (key instanceof Double || key instanceof Float) { 328 | if (!fullFloat) s = fmt.format(key); 329 | } 330 | 331 | String from = "%" + count + "%"; 332 | String to = s; 333 | str = str.replace(from, to); 334 | count++; 335 | } 336 | 337 | return TextFormat.colorize(str); 338 | } 339 | 340 | private void initMessage(String message) { 341 | this.message = message; 342 | } 343 | 344 | private String message; 345 | 346 | Message(String msg) { 347 | message = msg; 348 | } 349 | 350 | @Override 351 | public String toString() { 352 | return this.getText("NOCOLOR"); 353 | } 354 | 355 | public static void init(PluginBase plg) { 356 | plugin = plg; 357 | 358 | language = Trading.getSettings().getLanguage(); 359 | if (language.equalsIgnoreCase("default")) 360 | language = Server.getInstance().getLanguage().getLang(); 361 | else if (language.length() > 3) 362 | language = language.substring(0, 3); 363 | 364 | initMessages(); 365 | 366 | if (Trading.getSettings().saveLanguageFile()) { 367 | saveMessages(); 368 | } 369 | } 370 | 371 | private static void initMessages() { 372 | File f = new File(plugin.getDataFolder() + File.separator + language + ".lng"); 373 | Config lng; 374 | if (!f.exists()) { 375 | lng = new Config(f, Config.YAML); 376 | InputStream is = plugin.getClass().getResourceAsStream("/lang/" + language + ".lng"); 377 | lng.load(is); 378 | if (!f.delete()) { 379 | System.gc(); 380 | f.delete(); 381 | } 382 | } else lng = new Config(f, Config.YAML); 383 | for (Message key : Message.values()) 384 | key.initMessage(lng.getString(key.name().toLowerCase(), key.message)); 385 | } 386 | 387 | private static void saveMessages() { 388 | File f = new File(plugin.getDataFolder() + File.separator + language + ".lng"); 389 | Config lng = new Config(f, Config.YAML); 390 | for (Message key : Message.values()) 391 | lng.set(key.name().toLowerCase(), key.message); 392 | try { 393 | lng.save(); 394 | } catch (Exception e) { 395 | LNG_SAVE_FAIL.log(); 396 | } 397 | } 398 | 399 | } -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/Settings.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface; 2 | 3 | import cn.nukkit.plugin.Plugin; 4 | import cn.nukkit.utils.SimpleConfig; 5 | import me.onebone.economyapi.EconomyAPI; 6 | 7 | /** 8 | * Created by Leonidius20 on 05.01.18. 9 | */ 10 | public class Settings extends SimpleConfig { 11 | 12 | public Settings(Plugin plugin) { 13 | super(plugin); 14 | } 15 | 16 | @Override 17 | public boolean load() { 18 | boolean result = super.load(); 19 | currency = EconomyAPI.getInstance().getMonetaryUnit(); 20 | return result; 21 | } 22 | 23 | @Path(value = "save-translation") 24 | private boolean saveTranslation = false; 25 | 26 | @Path(value = "language") 27 | private String language = "default"; 28 | 29 | @Path(value = "edit-logging") 30 | private boolean editLogging = true; 31 | 32 | @Path(value = "transaction-logging") 33 | private boolean transactionLogging = false; 34 | 35 | @Path(value = "debug") 36 | private boolean debugMode = false; 37 | 38 | private String currency; 39 | 40 | public boolean saveLanguageFile() { 41 | return saveTranslation; 42 | } 43 | 44 | public String getLanguage() { 45 | return language; 46 | } 47 | 48 | public boolean logEdits() { 49 | return editLogging; 50 | } 51 | 52 | public boolean logTransactions() { 53 | return transactionLogging; 54 | } 55 | 56 | public boolean debugActive() { 57 | return debugMode; 58 | } 59 | 60 | public String getCurrency() { 61 | return currency; 62 | } 63 | 64 | } -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/ShopCommand.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface; 2 | 3 | import cn.nukkit.Player; 4 | import cn.nukkit.command.Command; 5 | import cn.nukkit.command.CommandExecutor; 6 | import cn.nukkit.command.CommandSender; 7 | import cn.nukkit.command.PluginCommand; 8 | import com.j256.ormlite.dao.Dao; 9 | import com.j256.ormlite.dao.DaoManager; 10 | import ua.leonidius.trdinterface.controllers.InfoController; 11 | import ua.leonidius.trdinterface.controllers.MainController; 12 | import ua.leonidius.trdinterface.models.Shop; 13 | import ua.leonidius.trdinterface.views.ScreenManager; 14 | 15 | import java.sql.SQLException; 16 | 17 | /** 18 | * Created by Leonidius20 on 07.01.18. 19 | */ 20 | public class ShopCommand extends PluginCommand implements CommandExecutor { 21 | 22 | ShopCommand(Trading owner) { 23 | super("shop", owner); 24 | setExecutor(this); 25 | setDescription(Message.CMD_SHOP.getText()); 26 | getCommandParameters().clear(); 27 | } 28 | 29 | public boolean onCommand(CommandSender sender, Command command, String s, String[] args) { 30 | if (!sender.isPlayer()) { 31 | Message.CMD_CONSOLE.print(sender); 32 | return true; 33 | } 34 | 35 | Player player = sender.getServer().getPlayer(sender.getName()); 36 | if (player == null) return false; 37 | 38 | ScreenManager manager = new ScreenManager(player); 39 | 40 | try { 41 | Dao shopDao = DaoManager.createDao(Trading.getSource(), Shop.class); 42 | Shop shop = shopDao.queryForId(1); // default shop has record_id = 1 43 | new MainController(manager, shop).showScreen(); 44 | } catch (SQLException e) { 45 | Trading.printException(e); 46 | new InfoController(manager, Message.ERROR.getText()); 47 | } 48 | 49 | return true; 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/Trading.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface; 2 | 3 | import cn.nukkit.event.EventHandler; 4 | import cn.nukkit.event.EventPriority; 5 | import cn.nukkit.event.Listener; 6 | import cn.nukkit.event.player.PlayerFormRespondedEvent; 7 | import cn.nukkit.form.window.FormWindowCustom; 8 | import cn.nukkit.form.window.FormWindowModal; 9 | import cn.nukkit.form.window.FormWindowSimple; 10 | import cn.nukkit.plugin.PluginBase; 11 | import cn.nukkit.utils.Config; 12 | import com.j256.ormlite.dao.Dao; 13 | import com.j256.ormlite.dao.DaoManager; 14 | import com.j256.ormlite.support.ConnectionSource; 15 | import com.j256.ormlite.table.TableUtils; 16 | import ru.nukkit.dblib.DbLib; 17 | import ua.leonidius.trdinterface.models.*; 18 | import ua.leonidius.trdinterface.utils.YamlToDbConverter; 19 | import ua.leonidius.trdinterface.views.screens.Screen; 20 | 21 | import java.io.File; 22 | import java.lang.reflect.Field; 23 | import java.sql.SQLException; 24 | 25 | /** 26 | * Created by Leonidius20 on 07.01.18. 27 | */ 28 | public class Trading extends PluginBase implements Listener { 29 | 30 | private static Trading plugin; 31 | private static Settings settings; 32 | 33 | private static ConnectionSource source; 34 | 35 | @Override 36 | public void onEnable() { 37 | plugin = this; 38 | 39 | settings = new Settings(this); 40 | settings.load(); 41 | 42 | Message.init(this); 43 | 44 | getServer().getCommandMap().register("trd-interface", new ShopCommand(this)); 45 | 46 | getServer().getPluginManager().registerEvents(this, this); 47 | 48 | getDataFolder().mkdirs(); 49 | 50 | /* imageFolder = new File(getDataFolder(), "images"); 51 | imageFolder.mkdirs(); */ 52 | 53 | saveResource("config.yml"); 54 | 55 | source = DbLib.getConnectionSource( 56 | DbLib.getSqliteUrl(new File(getDataFolder(), "shops.db")), 57 | null, null); 58 | 59 | try { 60 | TableUtils.createTableIfNotExists(source, Shop.class); 61 | 62 | // Creating the default shop (accessed with /shop) 63 | Dao shopDao = DaoManager.createDao(source, Shop.class); 64 | shopDao.createIfNotExists(Shop.getDefault()); 65 | 66 | TableUtils.createTableIfNotExists(source, Category.class); 67 | TableUtils.createTableIfNotExists(source, BuyableItem.class); 68 | TableUtils.createTableIfNotExists(source, SellableItem.class); 69 | TableUtils.createTableIfNotExists(source, Discount.class); 70 | TableUtils.createTableIfNotExists(source, Translation.class); 71 | } catch (SQLException e) { 72 | getLogger().critical(e.getMessage()); 73 | getPluginLoader().disablePlugin(this); 74 | } 75 | 76 | // Converting old configs 77 | File buyableItemsFile = new File(getDataFolder(), "buyList.yml"); 78 | if (buyableItemsFile.exists()) { 79 | Message.LOG_BUYABLE_ITEMS_FOUND.log(); 80 | Config buyableItems = new Config(buyableItemsFile); 81 | if (YamlToDbConverter.convertBuyableItems(buyableItems)) { 82 | buyableItemsFile.delete(); 83 | } 84 | } 85 | 86 | File sellableItemsFile = new File(getDataFolder(), "sellList.yml"); 87 | if (sellableItemsFile.exists()) { 88 | Message.LOG_SELLABLE_ITEMS_FOUND.log(); 89 | Config sellableItems = new Config(sellableItemsFile); 90 | if (YamlToDbConverter.convertSellableItems(sellableItems)) { 91 | sellableItemsFile.delete(); 92 | } 93 | } 94 | 95 | File translationsFile = new File(getDataFolder(), "customItemNames.yml"); 96 | if (translationsFile.exists()) { 97 | Message.LOG_TRANSLATIONS_FOUND.log(); 98 | Config translations = new Config(translationsFile); 99 | if (YamlToDbConverter.convertTranslations(translations)) { 100 | translationsFile.delete(); 101 | } 102 | } 103 | } 104 | 105 | @Override 106 | public void onDisable() { 107 | source.closeQuietly(); 108 | } 109 | 110 | // Form response handler 111 | @EventHandler(ignoreCancelled = true, priority = EventPriority.NORMAL) 112 | public void onFormResponse(PlayerFormRespondedEvent event) { 113 | if (!(event.getWindow() instanceof Screen)) return; 114 | if (event.getResponse() == null) { 115 | return; 116 | } 117 | ((Screen) event.getWindow()).onResponse(event); 118 | 119 | // When we show a window object, which was already shown before, 120 | // from stack (see ScreenManager.back()), that window object 121 | // already has its 'response' field set from the previous 122 | // interaction with it. Because of that, when that 'reused' 123 | // window gets closed with the 'x' button, the 'response' field 124 | // is equal to the response from the previous interaction, which 125 | // is treated as if the button pressed during the previous 126 | // interaction was pressed again (i.e. an unrequested window is 127 | // being shown, instead of the whole interface closing). We need 128 | // to set 'response' to null so that if this windows gets reused, 129 | // it is treated as a "fresh" window. event.getWindow().setResponse(null) 130 | // results in a NullPointerException, so we use reflection instead. 131 | try { 132 | Class subclass; 133 | if (event.getWindow() instanceof FormWindowSimple) 134 | subclass = FormWindowSimple.class; 135 | else if (event.getWindow() instanceof FormWindowModal) 136 | subclass = FormWindowModal.class; 137 | else if (event.getWindow() instanceof FormWindowCustom) 138 | subclass = FormWindowCustom.class; 139 | else return; 140 | 141 | Field response = subclass.getDeclaredField("response"); 142 | boolean accessible = response.isAccessible(); 143 | response.setAccessible(true); 144 | response.set(event.getWindow(), null); 145 | response.setAccessible(accessible); 146 | } catch (NoSuchFieldException | IllegalAccessException e) { 147 | Trading.printException(e); 148 | } 149 | } 150 | 151 | public static Trading getPlugin() { 152 | return plugin; 153 | } 154 | 155 | public static ConnectionSource getSource() { 156 | return source; 157 | } 158 | 159 | public static Settings getSettings() { 160 | return settings; 161 | } 162 | 163 | /** 164 | * Prints exception details to the console. 165 | * 166 | * @param e exception to handle 167 | */ 168 | public static void printException(Exception e) { 169 | getPlugin().getLogger().error(e.getMessage()); 170 | e.printStackTrace(); 171 | } 172 | 173 | } -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/AddEnchantmentController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers; 2 | 3 | import cn.nukkit.item.Item; 4 | import cn.nukkit.item.enchantment.Enchantment; 5 | import cn.nukkit.nbt.NBTIO; 6 | import ua.leonidius.trdinterface.Message; 7 | import ua.leonidius.trdinterface.Trading; 8 | import ua.leonidius.trdinterface.models.BuyableItem; 9 | import ua.leonidius.trdinterface.models.ShopItem; 10 | import ua.leonidius.trdinterface.views.ScreenManager; 11 | import ua.leonidius.trdinterface.views.screens.buy.items.edit.enchantment.AddEnchantmentScreen; 12 | 13 | import java.io.IOException; 14 | import java.sql.SQLException; 15 | 16 | public class AddEnchantmentController extends BaseController { 17 | 18 | private final ShopItem item; 19 | 20 | public AddEnchantmentController(ScreenManager manager, ShopItem item) { 21 | super(manager); 22 | this.item = item; 23 | } 24 | 25 | @Override 26 | public void showScreen() { 27 | manager.addAndShow(new AddEnchantmentScreen(this), true); 28 | } 29 | 30 | public void selectEnchantment(int id, int level) { 31 | Item gameItem = item.toGameItem(); 32 | gameItem.addEnchantment(Enchantment.get(id).setLevel(level)); 33 | 34 | try { 35 | byte[] newNbtBytes = NBTIO.write(gameItem.getNamedTag()); 36 | item.setNbt(newNbtBytes); 37 | item.update(); 38 | } catch (IOException | SQLException e) { 39 | handleException(e); 40 | return; 41 | } 42 | 43 | if (Trading.getSettings().logEdits()) { 44 | if (item instanceof BuyableItem) { 45 | Message.LOG_BUY_ENCHANTMENT_ADDED.log(manager.getPlayer().getName(), 46 | Enchantment.get(id).getName(), level, 47 | gameItem.getName(), item.getItemId()); 48 | } else { 49 | Message.LOG_SELL_ENCHANTMENT_ADDED.log(manager.getPlayer().getName(), 50 | Enchantment.get(id).getName(), level, 51 | gameItem.getName(), item.getItemId()); 52 | } 53 | } 54 | 55 | manager.back(); 56 | } 57 | 58 | } 59 | 60 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/AmountSelectorController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers; 2 | 3 | import ua.leonidius.trdinterface.views.ScreenManager; 4 | 5 | public abstract class AmountSelectorController extends ItemDetailsViewController { 6 | 7 | public AmountSelectorController(ScreenManager manager) { 8 | super(manager); 9 | } 10 | 11 | public abstract void selectAmount(int amount); 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/BaseController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers; 2 | 3 | import ua.leonidius.trdinterface.Message; 4 | import ua.leonidius.trdinterface.Trading; 5 | import ua.leonidius.trdinterface.views.ScreenManager; 6 | 7 | public abstract class BaseController { 8 | 9 | protected final ScreenManager manager; 10 | 11 | public BaseController(ScreenManager manager) { 12 | this.manager = manager; 13 | } 14 | 15 | public abstract void showScreen(); 16 | 17 | public void back() { 18 | manager.back(); 19 | } 20 | 21 | protected void showErrorScreen() { 22 | new InfoController(manager, Message.ERROR.getText()).showScreen(); 23 | } 24 | 25 | protected void showErrorScreen(String message) { 26 | new InfoController(manager, Message.ERROR_DESC.getText(message)).showScreen(); 27 | } 28 | 29 | /** 30 | * Prints exception info to console if debug mode is on 31 | * and shows an error screen to the user 32 | * 33 | * @param e exception to handle 34 | */ 35 | protected void handleException(Exception e) { 36 | Trading.printException(e); 37 | showErrorScreen(); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/DeleteEnchantmentController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers; 2 | 3 | import cn.nukkit.item.Item; 4 | import cn.nukkit.item.enchantment.Enchantment; 5 | import cn.nukkit.nbt.NBTIO; 6 | import ua.leonidius.trdinterface.Message; 7 | import ua.leonidius.trdinterface.Trading; 8 | import ua.leonidius.trdinterface.models.BuyableItem; 9 | import ua.leonidius.trdinterface.models.ShopItem; 10 | import ua.leonidius.trdinterface.views.ScreenManager; 11 | import ua.leonidius.trdinterface.views.screens.ModalScreen; 12 | 13 | import java.io.IOException; 14 | import java.sql.SQLException; 15 | 16 | public class DeleteEnchantmentController extends ModalController { 17 | 18 | private final ShopItem item; 19 | private final Enchantment enchantment; 20 | 21 | public DeleteEnchantmentController(ScreenManager manager, 22 | ShopItem item, Enchantment enchantment) { 23 | super(manager); 24 | this.item = item; 25 | this.enchantment = enchantment; 26 | } 27 | 28 | @Override 29 | public void showScreen() { 30 | manager.addAndShow(new ModalScreen(Message.WDW_REMOVE_ENCHANTMENT_TITLE.getText(), 31 | Message.WDW_REMOVE_ENCHANTMENT_CONF.getText(getName(), item.getName()), 32 | this), true); 33 | } 34 | 35 | @Override 36 | public void onPositiveResponse() { 37 | // we need to save custom name & lore, because we update the NBT tag 38 | Item oldGameItem = item.toGameItem(); 39 | Item newGameItem = Item.fromString(item.getItemId()); 40 | 41 | if (!oldGameItem.getCustomName().equals("")) 42 | newGameItem.setCustomName(oldGameItem.getCustomName()); 43 | if (oldGameItem.getLore() != null && oldGameItem.getLore().length != 0) { 44 | newGameItem.setLore(oldGameItem.getLore()); 45 | } 46 | 47 | for (Enchantment e : oldGameItem.getEnchantments()) { 48 | if (e.getId() != enchantment.getId()) { 49 | newGameItem.addEnchantment(e); 50 | } 51 | } 52 | 53 | try { 54 | byte[] newNbtBytes = newGameItem.getNamedTag() == null 55 | ? null : NBTIO.write(newGameItem.getNamedTag()); 56 | item.setNbt(newNbtBytes); 57 | item.update(); 58 | } catch (IOException | SQLException e) { 59 | handleException(e); 60 | return; 61 | } 62 | 63 | if (Trading.getSettings().logEdits()) { 64 | if (item instanceof BuyableItem) { 65 | Message.LOG_BUY_ENCHANTMENT_REMOVED.log(manager.getPlayer().getName(), 66 | enchantment.getName(), enchantment.getLevel(), 67 | item.getName(), item.getItemId()); 68 | } else { 69 | Message.LOG_SELL_ENCHANTMENT_REMOVED.log(manager.getPlayer().getName(), 70 | enchantment.getName(), enchantment.getLevel(), 71 | item.getName(), item.getItemId()); 72 | } 73 | } 74 | 75 | item.resetGameItem(); // so that the list of enchantments in 76 | // ManageEnchantmentsController is updated 77 | 78 | manager.back(); 79 | } 80 | 81 | /** 82 | * @return a string with the name and the level of the enchantment 83 | */ 84 | private String getName() { 85 | return enchantment.getName() + " " + enchantment.getLevel(); 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/DeleteItemController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers; 2 | 3 | import com.j256.ormlite.dao.Dao; 4 | import com.j256.ormlite.dao.DaoManager; 5 | import ua.leonidius.trdinterface.Message; 6 | import ua.leonidius.trdinterface.Trading; 7 | import ua.leonidius.trdinterface.models.BuyableItem; 8 | import ua.leonidius.trdinterface.models.SellableItem; 9 | import ua.leonidius.trdinterface.models.ShopItem; 10 | import ua.leonidius.trdinterface.views.ScreenManager; 11 | import ua.leonidius.trdinterface.views.screens.ModalScreen; 12 | 13 | import java.sql.SQLException; 14 | 15 | public class DeleteItemController extends ModalController { 16 | 17 | private final ShopItem item; 18 | 19 | public DeleteItemController(ScreenManager manager, ShopItem item) { 20 | super(manager); 21 | this.item = item; 22 | } 23 | 24 | @Override 25 | public void showScreen() { 26 | manager.addAndShow(new ModalScreen(Message.WDW_DELETE_ITEM_TITLE.getText(), 27 | item instanceof BuyableItem ? 28 | Message.WDW_DELETE_BUY_ITEM_CONF.getText(item.getName()) 29 | : Message.WDW_DELETE_SELL_ITEM_CONF.getText(item.getName()), 30 | this), true); 31 | } 32 | 33 | 34 | @Override 35 | public void onPositiveResponse() { 36 | // Saving data for logging 37 | String itemName = item.getName(); 38 | String itemId = item.getItemId(); 39 | 40 | try { 41 | if (item instanceof BuyableItem) { 42 | Dao itemDao = 43 | DaoManager.createDao(Trading.getSource(), BuyableItem.class); 44 | ((BuyableItem) item).removeDiscount(); 45 | itemDao.delete((BuyableItem) item); 46 | } else { 47 | Dao itemDao = 48 | DaoManager.createDao(Trading.getSource(), SellableItem.class); 49 | itemDao.delete((SellableItem) item); 50 | } 51 | } catch (SQLException e) { 52 | handleException(e); 53 | return; 54 | } 55 | 56 | if (Trading.getSettings().logEdits()) { 57 | if (item instanceof BuyableItem) { 58 | Message.LOG_BUY_ITEM_DELETED.log(manager.getPlayer().getName(), 59 | itemName, itemId); 60 | } else Message.LOG_SELL_ITEM_DELETED.log(manager.getPlayer().getName(), 61 | itemName, itemId); 62 | 63 | } 64 | 65 | manager.backTwoScreens(); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/EditItemController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers; 2 | 3 | import cn.nukkit.item.enchantment.Enchantment; 4 | import ua.leonidius.trdinterface.Message; 5 | import ua.leonidius.trdinterface.Trading; 6 | import ua.leonidius.trdinterface.models.BuyableItem; 7 | import ua.leonidius.trdinterface.models.ShopItem; 8 | import ua.leonidius.trdinterface.views.ScreenManager; 9 | import ua.leonidius.trdinterface.views.screens.ItemDetailsEditScreen; 10 | 11 | import java.sql.SQLException; 12 | import java.util.Iterator; 13 | import java.util.LinkedList; 14 | 15 | public class EditItemController extends ItemDetailsEditController { 16 | 17 | private final ShopItem item; 18 | 19 | public EditItemController(ScreenManager manager, ShopItem item) { 20 | super(manager); 21 | this.item = item; 22 | } 23 | 24 | @Override 25 | public void showScreen() { 26 | manager.addAndShow(new ItemDetailsEditScreen(this, 27 | Message.WDW_EDIT_ITEM_TITLE.getText(), 28 | item.getItemId(), String.valueOf(item.getPurePrice()), 29 | item.toGameItem().getCustomName(), 30 | arrayToString(item.toGameItem().getLore())), true); 31 | } 32 | 33 | @Override 34 | public void submitDetails(String itemId, String priceS, 35 | String customName, String customLore) { 36 | String oldId = item.getItemId(); 37 | String oldName = item.getName(); 38 | String oldCustomName = item.toGameItem().getCustomName(); 39 | double oldPrice = item.getPurePrice(); 40 | String oldLore = arrayToString(item.toGameItem().getLore()); 41 | Enchantment[] oldEnchantments = item.toGameItem().getEnchantments(); 42 | 43 | try { 44 | ShopItem.populate(item, itemId, priceS, customName, 45 | customLore, oldEnchantments); 46 | } catch (IllegalArgumentException e) { // invalid input 47 | showErrorScreen(e.getMessage()); 48 | return; 49 | } 50 | 51 | // so that item.getName(), item.getLore() return updated info 52 | item.resetGameItem(); 53 | 54 | if (item.getItemId().equals(oldId) 55 | && item.getPurePrice() == oldPrice 56 | && customName.equals(oldCustomName) 57 | && customLore.equals(oldLore)) { 58 | manager.back(); 59 | return; 60 | } 61 | 62 | try { 63 | item.update(); 64 | } catch (SQLException e) { 65 | handleException(e); 66 | return; 67 | } 68 | 69 | if (Trading.getSettings().logEdits()) { 70 | LinkedList changes = new LinkedList<>(); 71 | 72 | if (!item.getItemId().equals(oldId)) { 73 | changes.add(Message.LOG_EDITED_ID.getText(oldId, item.getItemId())); 74 | } 75 | 76 | if (item.getPrice() != oldPrice) { 77 | changes.add(Message.LOG_EDITED_PRICE.getText(oldPrice, 78 | Trading.getSettings().getCurrency(), item.getPurePrice())); 79 | } 80 | 81 | if (!customName.equals(oldCustomName)) { 82 | if (oldCustomName.isEmpty()) { 83 | changes.add(Message.LOG_ADDED_CUSTOM_NAME.getText(customName)); 84 | } else if (customName.isEmpty()) { 85 | changes.add(Message.LOG_REMOVED_CUSTOM_NAME.getText(oldCustomName)); 86 | } else 87 | changes.add(Message.LOG_EDITED_NAME.getText( 88 | oldCustomName, customName)); 89 | } 90 | 91 | if (!customLore.equals(oldLore)) { 92 | if (oldLore.trim().isEmpty()) { 93 | changes.add(Message.LOG_ADDED_LORE.getText(customLore)); 94 | } else if (customLore.trim().isEmpty()) { 95 | changes.add(Message.LOG_REMOVED_LORE.getText(oldLore)); 96 | } else changes.add(Message.LOG_EDITED_LORE.getText(oldLore, customLore)); 97 | } 98 | 99 | if (item instanceof BuyableItem) { 100 | Message.LOG_BUY_ITEM_EDITED.log(manager.getPlayer().getName(), 101 | oldName, listToString(changes)); 102 | } else { 103 | Message.LOG_SELL_ITEM_EDITED.log(manager.getPlayer().getName(), 104 | oldName, listToString(changes)); 105 | } 106 | 107 | } 108 | 109 | manager.back(); 110 | } 111 | 112 | /** 113 | * Joins an array of strings into a string, divided by line break 114 | * 115 | * @param array array of strings 116 | * @return resulting string 117 | */ 118 | private static String arrayToString(String[] array) { 119 | StringBuilder sb = new StringBuilder(); 120 | for (int i = 0; i < array.length; i++) { 121 | if (i != 0) sb.append('\n'); 122 | sb.append(array[i]); 123 | } 124 | return sb.toString(); 125 | } 126 | 127 | /** 128 | * Joins a list of strings into a string, divided by commas 129 | * 130 | * @param list list of strings 131 | * @return resulting string 132 | */ 133 | private static String listToString(LinkedList list) { 134 | StringBuilder sb = new StringBuilder(); 135 | int length = list.size(); 136 | Iterator iterator = list.iterator(); 137 | for (int i = 0; i < length; i++) { 138 | sb.append(iterator.next()); 139 | if (i != length - 1) sb.append(", "); 140 | } 141 | return sb.toString(); 142 | } 143 | 144 | } 145 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/InfoController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers; 2 | 3 | import ua.leonidius.trdinterface.views.ScreenManager; 4 | import ua.leonidius.trdinterface.views.screens.InfoScreen; 5 | 6 | public class InfoController extends BaseController { 7 | 8 | private final String title; 9 | private final String content; 10 | 11 | public InfoController(ScreenManager manager, String content) { 12 | super(manager); 13 | this.title = ""; 14 | this.content = content; 15 | } 16 | 17 | public InfoController(ScreenManager manager, String title, String content) { 18 | super(manager); 19 | this.title = title; 20 | this.content = content; 21 | } 22 | 23 | @Override 24 | public void showScreen() { 25 | manager.addAndShow(new InfoScreen(this, title, content), true); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/ItemDetailsEditController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers; 2 | 3 | import ua.leonidius.trdinterface.views.ScreenManager; 4 | 5 | public abstract class ItemDetailsEditController extends BaseController { 6 | 7 | public ItemDetailsEditController(ScreenManager manager) { 8 | super(manager); 9 | } 10 | 11 | public abstract void submitDetails(String itemId, String priceS, 12 | String customName, String customLore); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/ItemDetailsViewController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers; 2 | 3 | import cn.nukkit.item.Item; 4 | import cn.nukkit.item.enchantment.Enchantment; 5 | import ua.leonidius.trdinterface.Message; 6 | import ua.leonidius.trdinterface.Trading; 7 | import ua.leonidius.trdinterface.models.BuyableItem; 8 | import ua.leonidius.trdinterface.models.Discount; 9 | import ua.leonidius.trdinterface.models.ShopItem; 10 | import ua.leonidius.trdinterface.utils.TimeUnit; 11 | import ua.leonidius.trdinterface.views.ScreenManager; 12 | 13 | public abstract class ItemDetailsViewController extends BaseController { 14 | 15 | public ItemDetailsViewController(ScreenManager manager) { 16 | super(manager); 17 | } 18 | 19 | protected abstract ShopItem getItem(); 20 | 21 | public String buildItemDescription() { 22 | StringBuilder sb = new StringBuilder(); 23 | 24 | getItem().resetGameItem(); 25 | 26 | Item gameItem = getItem().toGameItem(); 27 | 28 | sb.append(Message.WDW_BUY_NAME.getText(getItem().getName())); 29 | sb.append("\n"); 30 | 31 | sb.append(Message.WDW_BUY_ORIGINAL_NAME.getText( 32 | getItem().getOriginalName(), getItem().getItemId())); 33 | 34 | sb.append("\n").append(Message.WDW_BUY_PRICE.getText(getItem().getPrice(), 35 | Trading.getSettings().getCurrency())); 36 | 37 | // Adding discount info 38 | if (getItem() instanceof BuyableItem) { 39 | Discount discount = ((BuyableItem) getItem()).getDiscount(); 40 | if (discount != null) { 41 | sb.append("\n") 42 | .append(Message.WDW_BUY_DISCOUNT.getText( 43 | discount.getPercent(), formatTimeLeft(discount.getEndTime()))); 44 | sb.append("\n") 45 | .append(Message.WDW_BUY_ORIGINAL_PRICE.getText( 46 | ((BuyableItem) getItem()).getOriginalPrice(), 47 | Trading.getSettings().getCurrency())); 48 | } 49 | } 50 | 51 | if (gameItem.getLore() != null && gameItem.getLore().length != 0) { 52 | StringBuilder loreBuilder = new StringBuilder(); 53 | for (String line : gameItem.getLore()) { 54 | loreBuilder.append(line).append("\n"); 55 | } 56 | sb.append("\n") 57 | .append(Message.WDW_BUY_CUSTOM_LORE.getText( 58 | loreBuilder.toString())); 59 | } 60 | 61 | Enchantment[] enchantments = gameItem.getEnchantments(); 62 | if (enchantments != null && enchantments.length != 0) { 63 | sb.append("\n"); 64 | StringBuilder eListBuilder = new StringBuilder(); 65 | for (int i = 0; i < enchantments.length; i++) { 66 | Enchantment enchantment = enchantments[i]; 67 | eListBuilder.append(enchantment.getName()) 68 | .append(" ").append(enchantment.getLevel()); 69 | if (i != enchantments.length - 1) eListBuilder.append(", "); 70 | } 71 | sb.append(Message.WDW_BUY_ENCHANTMENTS.getText(eListBuilder.toString())); 72 | } 73 | 74 | return sb.toString(); 75 | } 76 | 77 | /** 78 | * Formats time left to a certain number of seconds since epoch 79 | * 80 | * @param timestamp seconds after epoch, must be bigger than the 81 | * current time, otherwise the result is 'infinity' 82 | * @return formatted string 83 | */ 84 | private static String formatTimeLeft(long timestamp) { 85 | long secondsLeft = timestamp - System.currentTimeMillis() / 1000; 86 | if (secondsLeft < 0) return Message.INFINITY.getText(); 87 | if (secondsLeft == 0) return "0"; 88 | 89 | StringBuilder sb = new StringBuilder(); 90 | long months = secondsLeft / TimeUnit.MONTHS.getMultiplier(); // integer division 91 | if (months > 0) { 92 | sb.append(months).append(" ").append(TimeUnit.MONTHS.getName()).append(" "); 93 | secondsLeft -= (months * TimeUnit.MONTHS.getMultiplier()); 94 | } 95 | 96 | long days = secondsLeft / TimeUnit.DAYS.getMultiplier(); 97 | if (days > 0) { 98 | sb.append(days).append(" ").append(TimeUnit.DAYS.getName()).append(" "); 99 | secondsLeft -= (days * TimeUnit.DAYS.getMultiplier()); 100 | } 101 | 102 | long hours = secondsLeft / TimeUnit.HOURS.getMultiplier(); 103 | if (hours > 0) { 104 | sb.append(hours).append(" ").append(TimeUnit.HOURS.getName()).append(" "); 105 | secondsLeft -= (hours * TimeUnit.HOURS.getMultiplier()); 106 | } 107 | 108 | long minutes = secondsLeft / TimeUnit.MINUTES.getMultiplier(); 109 | if (minutes > 0) { 110 | sb.append(minutes).append(" ").append(TimeUnit.MINUTES.getName()).append(" "); 111 | secondsLeft -= (minutes * TimeUnit.MINUTES.getMultiplier()); 112 | } 113 | 114 | if (secondsLeft > 0) { 115 | sb.append(secondsLeft).append(" ").append(Message.SECONDS.getText()); 116 | } 117 | 118 | return sb.toString(); 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/ListController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers; 2 | 3 | import ua.leonidius.trdinterface.views.ScreenManager; 4 | 5 | import java.util.Collection; 6 | 7 | public abstract class ListController extends BaseController { 8 | 9 | public ListController(ScreenManager manager) { 10 | super(manager); 11 | } 12 | 13 | public abstract Collection fetchItems(); 14 | 15 | public abstract void selectItem(T item); 16 | 17 | public abstract String buildItemButtonText(T item); 18 | 19 | /** 20 | * Called in ListScreen's update() to refresh title 21 | * (e.g. after buyable items category rename) 22 | * @return title 23 | */ 24 | public abstract String getTitle(); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/MainController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers; 2 | 3 | import ua.leonidius.trdinterface.controllers.buy.categories.CategoriesListController; 4 | import ua.leonidius.trdinterface.controllers.sell.SellableItemsListController; 5 | import ua.leonidius.trdinterface.controllers.translations.TranslationsListController; 6 | import ua.leonidius.trdinterface.models.Shop; 7 | import ua.leonidius.trdinterface.views.ScreenManager; 8 | import ua.leonidius.trdinterface.views.screens.MainScreen; 9 | 10 | public class MainController extends BaseController { 11 | 12 | private final Shop shop; 13 | 14 | public MainController(ScreenManager manager, Shop shop) { 15 | super(manager); 16 | this.shop = shop; 17 | } 18 | 19 | @Override 20 | public void showScreen() { 21 | manager.addAndShow(new MainScreen(this)); 22 | } 23 | 24 | public void buy() { 25 | new CategoriesListController(manager, shop).showScreen(); 26 | } 27 | 28 | public void sell() { 29 | new SellableItemsListController(manager, shop).showScreen(); 30 | } 31 | 32 | public boolean showCustomNamesButton() { 33 | // TODO: check divided permissions 34 | return manager.getPlayer().hasPermission("shop.edit"); 35 | } 36 | 37 | public void customNames() { 38 | new TranslationsListController(manager).showScreen(); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/ManageEnchantmentsController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers; 2 | 3 | import cn.nukkit.item.enchantment.Enchantment; 4 | import ua.leonidius.trdinterface.Message; 5 | import ua.leonidius.trdinterface.models.ShopItem; 6 | import ua.leonidius.trdinterface.views.ScreenManager; 7 | import ua.leonidius.trdinterface.views.screens.ListScreen; 8 | 9 | import java.util.Arrays; 10 | import java.util.Collection; 11 | import java.util.LinkedHashMap; 12 | 13 | public class ManageEnchantmentsController extends ListController { 14 | 15 | private final ShopItem item; 16 | 17 | public ManageEnchantmentsController(ScreenManager manager, ShopItem item) { 18 | super(manager); 19 | this.item = item; 20 | } 21 | 22 | @Override 23 | public void showScreen() { 24 | LinkedHashMap buttons = 25 | new LinkedHashMap<>(); 26 | 27 | // TODO: check divided permissions 28 | if (manager.getPlayer().hasPermission("shop.edit")) { 29 | buttons.put(Message.BTN_ADD_ENCHANTMENT.getText(), this::addEnchantment); 30 | } 31 | 32 | manager.addAndShow(new ListScreen<>(this, 33 | Message.WDW_MANAGE_ENCHANTMENTS_EMPTY.getText(), 34 | Message.WDW_MANAGE_ENCHANTMENTS_TEXT.getText(), buttons)); 35 | } 36 | 37 | @Override 38 | public Collection fetchItems() { 39 | return Arrays.asList(item.toGameItem().getEnchantments()); 40 | } 41 | 42 | @Override 43 | public void selectItem(Enchantment e) { 44 | new DeleteEnchantmentController(manager, item, e).showScreen(); 45 | } 46 | 47 | private void addEnchantment() { 48 | new AddEnchantmentController(manager, item).showScreen(); 49 | } 50 | 51 | @Override 52 | public String buildItemButtonText(Enchantment enchantment) { 53 | return enchantment.getName() + " " + enchantment.getLevel(); 54 | } 55 | 56 | @Override 57 | public String getTitle() { 58 | return Message.WDW_MANAGE_ENCHANTMENTS_TITLE.getText(item.getName()); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/ModalController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers; 2 | 3 | import ua.leonidius.trdinterface.views.ScreenManager; 4 | 5 | public abstract class ModalController extends BaseController { 6 | 7 | public ModalController(ScreenManager manager) { 8 | super(manager); 9 | } 10 | 11 | public abstract void onPositiveResponse(); 12 | 13 | public void onNegativeResponse() { 14 | manager.back(); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/NamingController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers; 2 | 3 | import ua.leonidius.trdinterface.views.ScreenManager; 4 | import ua.leonidius.trdinterface.views.screens.NamingScreen; 5 | 6 | /** 7 | * This is a base class for a controller for NamingScreen 8 | */ 9 | public abstract class NamingController extends BaseController { 10 | 11 | public NamingController(ScreenManager manager) { 12 | super(manager); 13 | } 14 | 15 | protected abstract String getScreenTitle(); 16 | 17 | protected abstract String getInputFieldHint(); 18 | 19 | protected String getDefaultText() { 20 | return ""; 21 | } 22 | 23 | @Override 24 | public void showScreen() { 25 | manager.addAndShow(new NamingScreen(this, 26 | getScreenTitle(), getInputFieldHint(), 27 | getDefaultText()), true); 28 | } 29 | 30 | public abstract void submitName(String name); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/buy/categories/CategoriesListController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.buy.categories; 2 | 3 | import ua.leonidius.trdinterface.Message; 4 | import ua.leonidius.trdinterface.controllers.ListController; 5 | import ua.leonidius.trdinterface.controllers.buy.categories.edit.AddCategoryController; 6 | import ua.leonidius.trdinterface.controllers.buy.items.BuyableItemsListController; 7 | import ua.leonidius.trdinterface.models.Category; 8 | import ua.leonidius.trdinterface.models.Shop; 9 | import ua.leonidius.trdinterface.views.ScreenManager; 10 | import ua.leonidius.trdinterface.views.screens.ListScreen; 11 | 12 | import java.util.Collection; 13 | import java.util.LinkedHashMap; 14 | 15 | public class CategoriesListController extends ListController { 16 | 17 | private final Shop shop; 18 | 19 | public CategoriesListController(ScreenManager manager, Shop shop) { 20 | super(manager); 21 | this.shop = shop; 22 | } 23 | 24 | @Override 25 | public void showScreen() { 26 | LinkedHashMap buttons = 27 | new LinkedHashMap<>(); 28 | 29 | // TODO: check divided permissions 30 | if (manager.getPlayer().hasPermission("shop.edit")) { 31 | buttons.put(Message.BTN_ADD_CATEGORY.getText(), this::addCategory); 32 | } 33 | 34 | manager.addAndShow(new ListScreen<>(this, 35 | Message.WDW_BUY_NO_CATEGORIES.getText(), buttons)); 36 | } 37 | 38 | public boolean showEditingButtons() { 39 | // TODO: check divided permissions 40 | return manager.getPlayer().hasPermission("shop.edit"); 41 | } 42 | 43 | @Override 44 | public Collection fetchItems() { 45 | return shop.buyableItemsCategories; 46 | } 47 | 48 | @Override 49 | public String buildItemButtonText(Category category) { 50 | return category.getName(); 51 | } 52 | 53 | @Override 54 | public String getTitle() { 55 | return Message.WDW_BUY_CAT_TITLE.getText(); 56 | } 57 | 58 | public void addCategory() { 59 | new AddCategoryController(manager, shop).showScreen(); 60 | } 61 | 62 | @Override 63 | public void selectItem(Category category) { 64 | new BuyableItemsListController(manager, category).showScreen(); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/buy/categories/edit/AddCategoryController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.buy.categories.edit; 2 | 3 | import com.j256.ormlite.dao.Dao; 4 | import com.j256.ormlite.dao.DaoManager; 5 | import ua.leonidius.trdinterface.Message; 6 | import ua.leonidius.trdinterface.Trading; 7 | import ua.leonidius.trdinterface.controllers.InfoController; 8 | import ua.leonidius.trdinterface.controllers.NamingController; 9 | import ua.leonidius.trdinterface.models.Category; 10 | import ua.leonidius.trdinterface.models.Shop; 11 | import ua.leonidius.trdinterface.views.ScreenManager; 12 | 13 | import java.sql.SQLException; 14 | 15 | public class AddCategoryController extends NamingController { 16 | 17 | private final Shop shop; 18 | 19 | public AddCategoryController(ScreenManager manager, Shop shop) { 20 | super(manager); 21 | this.shop = shop; 22 | } 23 | 24 | @Override 25 | protected String getScreenTitle() { 26 | return Message.WDW_NEW_CATEGORY.getText(); 27 | } 28 | 29 | @Override 30 | protected String getInputFieldHint() { 31 | return Message.WDW_NEW_CATEGORY_NAME.getText(); 32 | } 33 | 34 | @Override 35 | public void submitName(String name) { 36 | try { 37 | Dao categoryDao = 38 | DaoManager.createDao(Trading.getSource(), Category.class); 39 | 40 | if (categoryDao.queryForEq("name", name).size() != 0) { 41 | new InfoController(manager, 42 | Message.WDW_NEW_CATEGORY_FAIL.getText()).showScreen(); 43 | return; 44 | } 45 | 46 | Category newCategory = new Category(shop, name); 47 | categoryDao.create(newCategory); 48 | 49 | if (Trading.getSettings().logEdits()) { 50 | Message.LOG_CATEGORY_ADDED.log(manager.getPlayer().getName(), name); 51 | } 52 | 53 | manager.back(); 54 | } catch (SQLException e) { 55 | Trading.printException(e); 56 | 57 | new InfoController(manager, Message.ERROR.getText()).showScreen(); 58 | } 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/buy/categories/edit/DeleteCategoryController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.buy.categories.edit; 2 | 3 | import com.j256.ormlite.dao.Dao; 4 | import com.j256.ormlite.dao.DaoManager; 5 | import ua.leonidius.trdinterface.Message; 6 | import ua.leonidius.trdinterface.Trading; 7 | import ua.leonidius.trdinterface.controllers.ModalController; 8 | import ua.leonidius.trdinterface.models.BuyableItem; 9 | import ua.leonidius.trdinterface.models.Category; 10 | import ua.leonidius.trdinterface.views.ScreenManager; 11 | import ua.leonidius.trdinterface.views.screens.ModalScreen; 12 | 13 | import java.sql.SQLException; 14 | 15 | public class DeleteCategoryController extends ModalController { 16 | 17 | private final Category category; 18 | 19 | public DeleteCategoryController(ScreenManager manager, Category category) { 20 | super(manager); 21 | this.category = category; 22 | } 23 | 24 | @Override 25 | public void showScreen() { 26 | manager.addAndShow(new ModalScreen(Message.WDW_DELETE_CATEGORY_TITLE.getText(), 27 | Message.WDW_DELETE_CATEGORY_CONF.getText(category.getName()), 28 | this), true); 29 | } 30 | 31 | @Override 32 | public void onPositiveResponse() { 33 | try { 34 | for (BuyableItem item : category.items) { 35 | item.removeDiscount(); 36 | category.items.getDao().delete(item); 37 | } 38 | 39 | Dao categoryDao = 40 | DaoManager.createDao(Trading.getSource(), Category.class); 41 | categoryDao.delete(category); 42 | 43 | if (Trading.getSettings().logEdits()) { 44 | Message.LOG_CATEGORY_DELETED.log(manager.getPlayer().getName(), 45 | category.getName()); 46 | } 47 | 48 | manager.backTwoScreens(); 49 | } catch (SQLException e) { 50 | handleException(e); 51 | } 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/buy/categories/edit/RenameCategoryController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.buy.categories.edit; 2 | 3 | import com.j256.ormlite.dao.Dao; 4 | import com.j256.ormlite.dao.DaoManager; 5 | import ua.leonidius.trdinterface.Message; 6 | import ua.leonidius.trdinterface.Trading; 7 | import ua.leonidius.trdinterface.controllers.InfoController; 8 | import ua.leonidius.trdinterface.controllers.NamingController; 9 | import ua.leonidius.trdinterface.models.Category; 10 | import ua.leonidius.trdinterface.views.ScreenManager; 11 | 12 | import java.sql.SQLException; 13 | 14 | public class RenameCategoryController extends NamingController { 15 | 16 | private final Category category; 17 | 18 | public RenameCategoryController(ScreenManager manager, Category category) { 19 | super(manager); 20 | this.category = category; 21 | } 22 | 23 | @Override 24 | protected String getScreenTitle() { 25 | return Message.WDW_RENAME_CATEGORY_TITLE.getText(); 26 | } 27 | 28 | @Override 29 | protected String getInputFieldHint() { 30 | return Message.WDW_RENAME_CATEGORY_NAME.getText(); 31 | } 32 | 33 | @Override 34 | protected String getDefaultText() { 35 | return category.getName(); 36 | } 37 | 38 | @Override 39 | public void submitName(String name) { 40 | String oldName = category.getName(); 41 | 42 | if (oldName.equals(name)) { 43 | manager.back(); 44 | return; 45 | } 46 | 47 | try { 48 | Dao categoryDao = 49 | DaoManager.createDao(Trading.getSource(), Category.class); 50 | 51 | if (categoryDao.queryForEq("name", name).size() != 0) { 52 | new InfoController(manager, 53 | Message.WDW_NEW_CATEGORY_FAIL.getText()).showScreen(); 54 | return; 55 | } 56 | 57 | category.setName(name); 58 | categoryDao.update(category); 59 | 60 | if (Trading.getSettings().logEdits()) { 61 | Message.LOG_CATEGORY_RENAMED.log(manager.getPlayer().getName(), 62 | oldName, name); 63 | } 64 | 65 | manager.back(); 66 | } catch (SQLException e) { 67 | handleException(e); 68 | } 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/buy/items/BuyAmountSelectorController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.buy.items; 2 | 3 | import cn.nukkit.inventory.PlayerInventory; 4 | import cn.nukkit.item.Item; 5 | import me.onebone.economyapi.EconomyAPI; 6 | import ua.leonidius.trdinterface.Message; 7 | import ua.leonidius.trdinterface.Trading; 8 | import ua.leonidius.trdinterface.controllers.AmountSelectorController; 9 | import ua.leonidius.trdinterface.controllers.InfoController; 10 | import ua.leonidius.trdinterface.models.BuyableItem; 11 | import ua.leonidius.trdinterface.models.ShopItem; 12 | import ua.leonidius.trdinterface.views.ScreenManager; 13 | import ua.leonidius.trdinterface.views.screens.AmountSelectorScreen; 14 | 15 | public class BuyAmountSelectorController extends AmountSelectorController { 16 | 17 | private final BuyableItem item; 18 | 19 | public BuyAmountSelectorController(ScreenManager manager, BuyableItem item) { 20 | super(manager); 21 | this.item = item; 22 | } 23 | 24 | @Override 25 | public void showScreen() { 26 | // Checking if there is enough place in inventory and money 27 | double price = item.getPrice(); 28 | 29 | int maxByMoney = getMaxByMoney(price); 30 | int maxByInventory = getMaxByInventory(); 31 | 32 | if (maxByMoney == 0 && maxByInventory == 0) { 33 | showInfoScreen(Message.WDW_VIEWING_BUYABLE_ITEM.getText(), 34 | buildItemDescription() 35 | + "\n\n" + Message.BUY_NO_SPACE_AND_MONEY.getText()); 36 | } else if (maxByMoney == 0) { 37 | showInfoScreen(Message.WDW_VIEWING_BUYABLE_ITEM.getText(), 38 | buildItemDescription() 39 | + "\n\n" + Message.BUY_NO_MONEY.getText()); 40 | } else if (maxByInventory == 0) { 41 | showInfoScreen(Message.WDW_VIEWING_BUYABLE_ITEM.getText(), 42 | buildItemDescription() 43 | + "\n\n" + Message.BUY_NO_SPACE.getText()); 44 | } else { 45 | int maxAmount = Math.min(maxByInventory, maxByMoney); 46 | manager.addAndShow(new AmountSelectorScreen(this, 47 | Message.WDW_BUY_TITLE.getText(item.toGameItem().getName()), 48 | buildItemDescription(), maxAmount), true); 49 | } 50 | } 51 | 52 | @Override 53 | public void selectAmount(int amount) { 54 | double price = item.getPrice(); 55 | double cost = amount * price; 56 | 57 | Item gameItem = item.toGameItem(); 58 | gameItem.setCount(amount); 59 | 60 | // Check in case player has lost money between selecting an item 61 | // and confirming buying 62 | if (EconomyAPI.getInstance().myMoney(manager.getPlayer()) < cost) { 63 | showInfoScreen(Message.WDW_FAIL_TITLE.getText(), 64 | Message.BUY_NO_MONEY.getText()); 65 | return; 66 | } 67 | 68 | // Check in case something was added to the player's inventory 69 | // between selecting an item and confirming buying and now 70 | // there is not enough space 71 | if (!manager.getPlayer().getInventory().canAddItem(gameItem)) { 72 | showInfoScreen(Message.WDW_FAIL_TITLE.getText(), 73 | Message.BUY_NO_SPACE.getText()); 74 | return; 75 | } 76 | 77 | EconomyAPI.getInstance().reduceMoney(manager.getPlayer(), cost); 78 | manager.getPlayer().getInventory().addItem(gameItem); 79 | 80 | if (Trading.getSettings().logTransactions()) { 81 | Message.LOG_BOUGHT.log(manager.getPlayer().getName(), 82 | amount, item.getName(), item.getItemId(), 83 | cost, Trading.getSettings().getCurrency()); 84 | } 85 | 86 | showInfoScreen(Message.WDW_SUCCESS_TITLE.getText(), 87 | Message.BUY_SUCCESS.getText(amount, item.getName(), 88 | cost, Trading.getSettings().getCurrency())); 89 | } 90 | 91 | @Override 92 | protected ShopItem getItem() { 93 | return item; 94 | } 95 | 96 | private int getMaxByMoney(double priceWithDiscount) { 97 | double money = EconomyAPI.getInstance().myMoney(manager.getPlayer()); 98 | return (int) Math.floor(money / priceWithDiscount); 99 | } 100 | 101 | private int getMaxByInventory() { 102 | PlayerInventory inventory = manager.getPlayer().getInventory(); 103 | Item gameItem = item.toGameItem(); 104 | int maxStack = gameItem.getMaxStackSize(); 105 | int amount = 0; 106 | for (int i = 0; i < 36; i++) { 107 | Item itemInSlot = inventory.getItem(i); 108 | if (itemInSlot.getId() == Item.AIR) { 109 | amount += maxStack; 110 | } else if (itemInSlot.equals(gameItem, true, true)) { 111 | amount += (maxStack - itemInSlot.getCount()); 112 | } 113 | } 114 | return amount; 115 | } 116 | 117 | private void showInfoScreen(String title, String message) { 118 | new InfoController(manager, title, message).showScreen(); 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/buy/items/BuyableItemsListController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.buy.items; 2 | 3 | import cn.nukkit.item.Item; 4 | import cn.nukkit.utils.TextFormat; 5 | import ua.leonidius.trdinterface.Message; 6 | import ua.leonidius.trdinterface.Trading; 7 | import ua.leonidius.trdinterface.controllers.ListController; 8 | import ua.leonidius.trdinterface.controllers.buy.categories.edit.DeleteCategoryController; 9 | import ua.leonidius.trdinterface.controllers.buy.categories.edit.RenameCategoryController; 10 | import ua.leonidius.trdinterface.controllers.buy.items.edit.AddBuyableItemController; 11 | import ua.leonidius.trdinterface.controllers.buy.items.edit.ManageBuyableItemController; 12 | import ua.leonidius.trdinterface.models.BuyableItem; 13 | import ua.leonidius.trdinterface.models.Category; 14 | import ua.leonidius.trdinterface.models.Discount; 15 | import ua.leonidius.trdinterface.views.ScreenManager; 16 | import ua.leonidius.trdinterface.views.screens.ListScreen; 17 | 18 | import java.util.Collection; 19 | import java.util.LinkedHashMap; 20 | 21 | public class BuyableItemsListController extends ListController { 22 | 23 | private final Category category; 24 | 25 | public BuyableItemsListController(ScreenManager manager, Category category) { 26 | super(manager); 27 | this.category = category; 28 | } 29 | 30 | @Override 31 | public void showScreen() { 32 | LinkedHashMap buttons = 33 | new LinkedHashMap<>(); 34 | 35 | // TODO: check divided permissions 36 | if (manager.getPlayer().hasPermission("shop.edit")) { 37 | buttons.put(Message.BTN_RENAME_CATEGORY.getText(), this::renameCategory); 38 | buttons.put(Message.BTN_DELETE_CATEGORY.getText(), this::deleteCategory); 39 | buttons.put(Message.BTN_ADD_ITEM.getText(), this::addItem); 40 | } 41 | 42 | manager.addAndShow(new ListScreen<>(this, 43 | Message.WDW_BUY_EMPTY_CAT.getText(), buttons)); 44 | } 45 | 46 | @Override 47 | public Collection fetchItems() { 48 | Collection items = category.items; 49 | 50 | for (BuyableItem item : items) { 51 | Discount discount = item.getDiscount(); 52 | if (discount == null) continue; 53 | // for infinite discounts, copied from old yaml configs 54 | if (discount.getEndTime() == -1) continue; 55 | if (discount.getEndTime() <= (System.currentTimeMillis() / 1000)) { 56 | item.removeDiscount(); 57 | } 58 | } 59 | 60 | return items; 61 | } 62 | 63 | public void renameCategory() { 64 | new RenameCategoryController(manager, category).showScreen(); 65 | } 66 | 67 | public void deleteCategory() { 68 | new DeleteCategoryController(manager, category).showScreen(); 69 | } 70 | 71 | public void addItem() { 72 | new AddBuyableItemController(manager, category).showScreen(); 73 | } 74 | 75 | @Override 76 | public String getTitle() { 77 | return category.getName(); 78 | } 79 | 80 | @Override 81 | public void selectItem(BuyableItem item) { 82 | // TODO: check divided permissions 83 | if (manager.getPlayer().hasPermission("shop.edit")) { 84 | new ManageBuyableItemController(manager, item).showScreen(); 85 | return; 86 | } 87 | 88 | new BuyAmountSelectorController(manager, item).showScreen(); 89 | } 90 | 91 | @Override 92 | public String buildItemButtonText(BuyableItem item) { 93 | Item gameItem = item.toGameItem(); 94 | 95 | String result; 96 | 97 | if (item.getDiscount() != null) { 98 | result = Message.BTN_ITEM_BUY_SALE.getText(item.getName(), 99 | item.getPrice(), Trading.getSettings().getCurrency(), 100 | item.getDiscount().getPercent()); 101 | } else { 102 | result = Message.BTN_ITEM_BUY.getText(item.getName(), item.getPrice(), 103 | Trading.getSettings().getCurrency()); 104 | } 105 | 106 | 107 | if (gameItem.hasEnchantments()) { 108 | return TextFormat.colorize( 109 | "&" + TextFormat.DARK_PURPLE.getChar() + result 110 | + "&" + TextFormat.RESET.getChar()); 111 | } else return result; 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/buy/items/discounts/AddDiscountController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.buy.items.discounts; 2 | 3 | import ua.leonidius.trdinterface.Message; 4 | import ua.leonidius.trdinterface.Trading; 5 | import ua.leonidius.trdinterface.controllers.BaseController; 6 | import ua.leonidius.trdinterface.models.BuyableItem; 7 | import ua.leonidius.trdinterface.models.Discount; 8 | import ua.leonidius.trdinterface.utils.TimeUnit; 9 | import ua.leonidius.trdinterface.views.ScreenManager; 10 | import ua.leonidius.trdinterface.views.screens.buy.items.edit.AddDiscountScreen; 11 | 12 | public class AddDiscountController extends BaseController { 13 | 14 | private final BuyableItem item; 15 | 16 | public AddDiscountController(ScreenManager manager, BuyableItem item) { 17 | super(manager); 18 | this.item = item; 19 | } 20 | 21 | @Override 22 | public void showScreen() { 23 | manager.addAndShow(new AddDiscountScreen(this), true); 24 | } 25 | 26 | /** 27 | * Adding a temporary discount to a buyable item 28 | * 29 | * @param percentS string with the discount's size in percents 30 | * @param durationS string with the discount's duration in units, defined 31 | * by the 'multiplier' parameter 32 | * @param unit units, in which the discount's duration is measured 33 | */ 34 | public void addDiscount(String percentS, String durationS, TimeUnit unit) { 35 | double percent; 36 | double duration; 37 | 38 | try { 39 | percent = Double.parseDouble(percentS); 40 | 41 | if (percent == 0) { 42 | manager.back(); 43 | return; 44 | } 45 | 46 | if (percent > 100 || percent < 0) { 47 | showErrorScreen(Message.WDW_EDIT_DISCOUNT_MORE_THAN_100.getText()); 48 | return; 49 | } 50 | 51 | duration = Double.parseDouble(durationS); 52 | long creationTime = System.currentTimeMillis() / 1000L; 53 | long endTime = creationTime + (long) (duration * unit.getMultiplier()); 54 | 55 | Discount discount = new Discount(item, percent, endTime); 56 | 57 | item.addDiscount(discount); 58 | 59 | if (Trading.getSettings().logEdits()) { 60 | Message.LOG_DISCOUNT_ADDED.log(manager.getPlayer().getName(), 61 | percent, item.getName(), 62 | item.getItemId(), duration, unit.getName()); 63 | } 64 | 65 | manager.back(); 66 | } catch (NumberFormatException e) { 67 | showErrorScreen(Message.WDW_INVALID_PARAMS.getText()); 68 | } 69 | } 70 | 71 | /** 72 | * Returns time units for AddDiscountScreen's dropdown menu 73 | * 74 | * @return array of time units 75 | * @see AddDiscountScreen 76 | */ 77 | public TimeUnit[] getTimeUnits() { 78 | return TimeUnit.values(); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/buy/items/discounts/RemoveDiscountController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.buy.items.discounts; 2 | 3 | import ua.leonidius.trdinterface.Message; 4 | import ua.leonidius.trdinterface.Trading; 5 | import ua.leonidius.trdinterface.controllers.ModalController; 6 | import ua.leonidius.trdinterface.models.BuyableItem; 7 | import ua.leonidius.trdinterface.views.ScreenManager; 8 | import ua.leonidius.trdinterface.views.screens.ModalScreen; 9 | 10 | public class RemoveDiscountController extends ModalController { 11 | 12 | private final BuyableItem item; 13 | 14 | public RemoveDiscountController(ScreenManager manager, BuyableItem item) { 15 | super(manager); 16 | this.item = item; 17 | } 18 | 19 | @Override 20 | public void showScreen() { 21 | manager.addAndShow(new ModalScreen("", 22 | Message.WDW_REMOVE_DISCOUNT_CONF.getText( 23 | item.getDiscount().getPercent(), item.getName()), 24 | this), true); 25 | } 26 | 27 | @Override 28 | public void onPositiveResponse() { 29 | item.removeDiscount(); 30 | 31 | if (Trading.getSettings().logEdits()) { 32 | Message.LOG_DISCOUNT_DELETED.log(manager.getPlayer().getName(), 33 | item.getName(), item.getItemId()); 34 | } 35 | 36 | manager.back(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/buy/items/edit/AddBuyableItemController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.buy.items.edit; 2 | 3 | import cn.nukkit.item.Item; 4 | import com.j256.ormlite.dao.Dao; 5 | import com.j256.ormlite.dao.DaoManager; 6 | import ua.leonidius.trdinterface.Message; 7 | import ua.leonidius.trdinterface.Trading; 8 | import ua.leonidius.trdinterface.controllers.InfoController; 9 | import ua.leonidius.trdinterface.controllers.ItemDetailsEditController; 10 | import ua.leonidius.trdinterface.models.BuyableItem; 11 | import ua.leonidius.trdinterface.models.Category; 12 | import ua.leonidius.trdinterface.views.ScreenManager; 13 | import ua.leonidius.trdinterface.views.screens.ItemDetailsEditScreen; 14 | 15 | import java.sql.SQLException; 16 | 17 | public class AddBuyableItemController extends ItemDetailsEditController { 18 | 19 | private final Category category; 20 | 21 | public AddBuyableItemController(ScreenManager manager, Category category) { 22 | super(manager); 23 | this.category = category; 24 | } 25 | 26 | @Override 27 | public void showScreen() { 28 | manager.addAndShow(new ItemDetailsEditScreen(this, 29 | Message.WDW_ADD_ITEM_TITLE.getText()), true); 30 | } 31 | 32 | @Override 33 | public void submitDetails(String itemId, String priceS, String customName, String customLore) { 34 | BuyableItem item = new BuyableItem(); 35 | item.setShop(category.getShop()); 36 | item.setCategory(category); 37 | 38 | try { 39 | BuyableItem.populate(item, itemId, priceS, customName, customLore); 40 | } catch (IllegalArgumentException e) { 41 | // we don't want this to be printed to console, 42 | // that's why we don't use handleException() 43 | showErrorScreen(e.getMessage()); 44 | return; 45 | } 46 | 47 | try { 48 | Dao itemDao = 49 | DaoManager.createDao(Trading.getSource(), BuyableItem.class); 50 | itemDao.create(item); 51 | itemDao.assignEmptyForeignCollection(item, "discounts"); 52 | } catch (SQLException e) { 53 | handleException(e); 54 | return; 55 | } 56 | 57 | if (Trading.getSettings().logEdits()) { 58 | if (customName == null || customName.equals("")) { 59 | Message.LOG_BUY_ITEM_ADDED.log(manager.getPlayer().getName(), item.getName(), 60 | item.getItemId(), item.getPrice(), 61 | Trading.getSettings().getCurrency()); 62 | } else { 63 | Message.LOG_BUY_ITEM_ADDED_WITH_CUSTOM_NAME.log(manager.getPlayer().getName(), customName, 64 | Item.fromString(item.getItemId()).getName(), 65 | item.getItemId(), item.getPrice(), 66 | Trading.getSettings().getCurrency()); 67 | } 68 | } 69 | 70 | new InfoController(manager, Message.WDW_SUCCESS_TITLE.getText(), 71 | Message.WDW_ADD_BUY_ITEM_SUCCESS.getText(item.getName())) 72 | .showScreen(); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/buy/items/edit/ManageBuyableItemController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.buy.items.edit; 2 | 3 | import ua.leonidius.trdinterface.controllers.DeleteItemController; 4 | import ua.leonidius.trdinterface.controllers.EditItemController; 5 | import ua.leonidius.trdinterface.controllers.ItemDetailsViewController; 6 | import ua.leonidius.trdinterface.controllers.ManageEnchantmentsController; 7 | import ua.leonidius.trdinterface.controllers.buy.items.BuyAmountSelectorController; 8 | import ua.leonidius.trdinterface.controllers.buy.items.discounts.AddDiscountController; 9 | import ua.leonidius.trdinterface.controllers.buy.items.discounts.RemoveDiscountController; 10 | import ua.leonidius.trdinterface.models.BuyableItem; 11 | import ua.leonidius.trdinterface.views.ScreenManager; 12 | import ua.leonidius.trdinterface.views.screens.buy.items.edit.ManageBuyableItemScreen; 13 | 14 | public class ManageBuyableItemController extends ItemDetailsViewController { 15 | 16 | private final BuyableItem item; 17 | 18 | public ManageBuyableItemController(ScreenManager manager, BuyableItem item) { 19 | super(manager); 20 | this.item = item; 21 | } 22 | 23 | @Override 24 | public void showScreen() { 25 | manager.addAndShow(new ManageBuyableItemScreen(this)); 26 | } 27 | 28 | @Override 29 | protected BuyableItem getItem() { 30 | return item; 31 | } 32 | 33 | public boolean hasDiscount() { 34 | return item.getDiscount() != null; 35 | } 36 | 37 | public void buyItem() { 38 | new BuyAmountSelectorController(manager, item).showScreen(); 39 | } 40 | 41 | public void editItem() { 42 | new EditItemController(manager, item).showScreen(); 43 | } 44 | 45 | public void addDiscount() { 46 | new AddDiscountController(manager, item).showScreen(); 47 | } 48 | 49 | public void removeDiscount() { 50 | new RemoveDiscountController(manager, item).showScreen(); 51 | } 52 | 53 | public void manageEnchantments() { 54 | new ManageEnchantmentsController(manager, item).showScreen(); 55 | } 56 | 57 | public void deleteItem() { 58 | new DeleteItemController(manager, item).showScreen(); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/sell/SellAmountSelectorController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.sell; 2 | 3 | import cn.nukkit.item.Item; 4 | import me.onebone.economyapi.EconomyAPI; 5 | import ua.leonidius.trdinterface.Message; 6 | import ua.leonidius.trdinterface.Trading; 7 | import ua.leonidius.trdinterface.controllers.AmountSelectorController; 8 | import ua.leonidius.trdinterface.controllers.InfoController; 9 | import ua.leonidius.trdinterface.models.SellableItem; 10 | import ua.leonidius.trdinterface.models.ShopItem; 11 | import ua.leonidius.trdinterface.views.ScreenManager; 12 | import ua.leonidius.trdinterface.views.screens.AmountSelectorScreen; 13 | 14 | public class SellAmountSelectorController extends AmountSelectorController { 15 | 16 | private final SellableItem item; 17 | private final int maxAmount; 18 | 19 | public SellAmountSelectorController(ScreenManager manager, 20 | SellableItem item, int maxAmount) { 21 | super(manager); 22 | this.item = item; 23 | this.maxAmount = maxAmount; 24 | } 25 | 26 | @Override 27 | public void showScreen() { 28 | manager.addAndShow(new AmountSelectorScreen(this, 29 | Message.WDW_SELL_TITLE.getText(item.getName()), 30 | buildItemDescription(), maxAmount), true); 31 | } 32 | 33 | @Override 34 | public void selectAmount(int amount) { 35 | Item gameItem = item.toGameItem(); 36 | gameItem.setCount(amount); 37 | 38 | if (!manager.getPlayer().getInventory().contains(gameItem)) { 39 | showErrorScreen(Message.WDW_SELL_NOTHING.getText()); 40 | return; 41 | } 42 | 43 | double cost = item.getPrice() * amount; 44 | 45 | manager.getPlayer().getInventory().removeItem(gameItem); 46 | EconomyAPI.getInstance().addMoney(manager.getPlayer(), cost); 47 | 48 | // Success 49 | if (Trading.getSettings().logTransactions()) { 50 | Message.LOG_SOLD.log(manager.getPlayer().getName(), amount, 51 | item.getName(), item.getItemId(), 52 | cost, Trading.getSettings().getCurrency()); 53 | } 54 | 55 | new InfoController(manager, Message.WDW_SUCCESS_TITLE.getText(), 56 | Message.SELL_SUCCESS.getText(amount, item.getName(), 57 | cost, Trading.getSettings().getCurrency())).showScreen(); 58 | } 59 | 60 | @Override 61 | protected ShopItem getItem() { 62 | return item; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/sell/SellableItemsListController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.sell; 2 | 3 | import cn.nukkit.item.Item; 4 | import cn.nukkit.utils.TextFormat; 5 | import com.j256.ormlite.dao.CloseableIterator; 6 | import ua.leonidius.trdinterface.Message; 7 | import ua.leonidius.trdinterface.Trading; 8 | import ua.leonidius.trdinterface.controllers.ListController; 9 | import ua.leonidius.trdinterface.controllers.sell.edit.EditSellableItemsController; 10 | import ua.leonidius.trdinterface.models.SellableItem; 11 | import ua.leonidius.trdinterface.models.Shop; 12 | import ua.leonidius.trdinterface.utils.ItemCompare; 13 | import ua.leonidius.trdinterface.views.ScreenManager; 14 | import ua.leonidius.trdinterface.views.screens.ListScreen; 15 | 16 | import java.util.Collection; 17 | import java.util.LinkedHashMap; 18 | import java.util.Map; 19 | 20 | public class SellableItemsListController 21 | extends ListController> { 22 | 23 | private final Shop shop; 24 | 25 | public SellableItemsListController(ScreenManager manager, Shop shop) { 26 | super(manager); 27 | this.shop = shop; 28 | } 29 | 30 | @Override 31 | public void showScreen() { 32 | LinkedHashMap buttons = 33 | new LinkedHashMap<>(); 34 | 35 | if (manager.getPlayer().hasPermission("shop.edit")) { 36 | buttons.put(Message.MENU_EDIT_SELL_LIST.getText(), this::editList); 37 | } else { 38 | buttons.put(Message.MENU_BROWSE_SELL_LIST.getText(), this::editList); 39 | } 40 | 41 | manager.addAndShow(new ListScreen<>(this, 42 | Message.WDW_SELL_NOTHING.getText(), buttons)); 43 | } 44 | 45 | @Override 46 | public void selectItem(Map.Entry item) { 47 | new SellAmountSelectorController(manager, 48 | item.getKey(), item.getValue()).showScreen(); 49 | } 50 | 51 | @Override 52 | public Collection> fetchItems() { 53 | CloseableIterator iterator = shop.sellableItems.closeableIterator(); 54 | 55 | // TODO: optimize 56 | LinkedHashMap itemsAndCounts = new LinkedHashMap<>(); 57 | 58 | while (iterator.hasNext()) { 59 | SellableItem item = iterator.next(); 60 | for (int i = 0; i < 36; i++) { 61 | Item itemInSlot = manager.getPlayer().getInventory().getItem(i); 62 | if (ItemCompare.equals(itemInSlot, item.toGameItem())) { 63 | if (itemsAndCounts.containsKey(item)) { 64 | itemsAndCounts.put(item, 65 | itemInSlot.getCount() + itemsAndCounts.get(item)); 66 | } else itemsAndCounts.put(item, itemInSlot.getCount()); 67 | } 68 | } 69 | } 70 | 71 | return itemsAndCounts.entrySet(); 72 | } 73 | 74 | @Override 75 | public String getTitle() { 76 | return Message.WDW_SELL_SELECT_ITEM.getText(); 77 | } 78 | 79 | public void editList() { 80 | new EditSellableItemsController(manager, shop).showScreen(); 81 | } 82 | 83 | @Override 84 | public String buildItemButtonText(Map.Entry entry) { 85 | SellableItem item = entry.getKey(); 86 | int amount = entry.getValue(); 87 | 88 | Item gameItem = item.toGameItem(); 89 | 90 | String result = Message.BTN_ITEM_SELL.getText(item.getName(), 91 | item.getPrice(), Trading.getSettings().getCurrency(), amount); 92 | 93 | if (gameItem.hasEnchantments()) { 94 | return TextFormat.colorize( 95 | "&" + TextFormat.DARK_PURPLE.getChar() + result 96 | + "&" + TextFormat.RESET.getChar()); 97 | } else return result; 98 | 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/sell/edit/AddSellableItemController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.sell.edit; 2 | 3 | import cn.nukkit.item.Item; 4 | import com.j256.ormlite.dao.Dao; 5 | import com.j256.ormlite.dao.DaoManager; 6 | import ua.leonidius.trdinterface.Message; 7 | import ua.leonidius.trdinterface.Trading; 8 | import ua.leonidius.trdinterface.controllers.InfoController; 9 | import ua.leonidius.trdinterface.controllers.ItemDetailsEditController; 10 | import ua.leonidius.trdinterface.models.SellableItem; 11 | import ua.leonidius.trdinterface.models.Shop; 12 | import ua.leonidius.trdinterface.views.ScreenManager; 13 | import ua.leonidius.trdinterface.views.screens.ItemDetailsEditScreen; 14 | 15 | import java.sql.SQLException; 16 | 17 | public class AddSellableItemController extends ItemDetailsEditController { 18 | 19 | private final Shop shop; 20 | 21 | public AddSellableItemController(ScreenManager manager, Shop shop) { 22 | super(manager); 23 | this.shop = shop; 24 | } 25 | 26 | @Override 27 | public void showScreen() { 28 | manager.addAndShow(new ItemDetailsEditScreen(this, 29 | Message.WDW_ADD_ITEM_TITLE.getText()), true); 30 | } 31 | 32 | @Override 33 | public void submitDetails(String itemId, String priceS, String customName, String customLore) { 34 | SellableItem item = new SellableItem(); 35 | item.setShop(shop); 36 | 37 | try { 38 | SellableItem.populate(item, itemId, priceS, customName, customLore); 39 | } catch (IllegalArgumentException e) { 40 | // we don't want this to be printed to console, 41 | // that's why we don't use handleException() 42 | showErrorScreen(e.getMessage()); 43 | return; 44 | } 45 | 46 | try { 47 | Dao itemDao = 48 | DaoManager.createDao(Trading.getSource(), SellableItem.class); 49 | itemDao.create(item); 50 | } catch (SQLException e) { 51 | handleException(e); 52 | return; 53 | } 54 | 55 | if (Trading.getSettings().logEdits()) { 56 | if (customName == null || customName.equals("")) { 57 | Message.LOG_SELL_ITEM_ADDED.log(manager.getPlayer().getName(), 58 | item.getName(), item.getItemId(), 59 | item.getPrice(), Trading.getSettings().getCurrency()); 60 | } else { 61 | Message.LOG_SELL_ITEM_ADDED_WITH_CUSTOM_NAME.log( 62 | manager.getPlayer().getName(), customName, 63 | Item.fromString(item.getItemId()).getName(), 64 | item.getItemId(), item.getPrice(), 65 | Trading.getSettings().getCurrency()); 66 | } 67 | } 68 | 69 | new InfoController(manager, Message.WDW_SUCCESS_TITLE.getText(), 70 | Message.WDW_ADD_SELL_ITEM_SUCCESS.getText(item.getName())) 71 | .showScreen(); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/sell/edit/EditSellableItemsController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.sell.edit; 2 | 3 | import cn.nukkit.item.Item; 4 | import cn.nukkit.utils.TextFormat; 5 | import ua.leonidius.trdinterface.Message; 6 | import ua.leonidius.trdinterface.Trading; 7 | import ua.leonidius.trdinterface.controllers.ListController; 8 | import ua.leonidius.trdinterface.models.SellableItem; 9 | import ua.leonidius.trdinterface.models.Shop; 10 | import ua.leonidius.trdinterface.views.ScreenManager; 11 | import ua.leonidius.trdinterface.views.screens.ListScreen; 12 | 13 | import java.util.Collection; 14 | import java.util.LinkedHashMap; 15 | 16 | /** 17 | * Controller for showing a list of all 18 | * sellable items in the shop to edit them 19 | */ 20 | public class EditSellableItemsController extends ListController { 21 | 22 | private final Shop shop; 23 | 24 | public EditSellableItemsController(ScreenManager manager, Shop shop) { 25 | super(manager); 26 | this.shop = shop; 27 | } 28 | 29 | @Override 30 | public void showScreen() { 31 | LinkedHashMap buttons = 32 | new LinkedHashMap<>(); 33 | 34 | // TODO: check divided permissions 35 | if (manager.getPlayer().hasPermission("shop.edit")) { 36 | buttons.put(Message.BTN_ADD_ITEM.getText(), this::addItem); 37 | } 38 | 39 | manager.addAndShow(new ListScreen<>(this, 40 | Message.WDW_EDIT_SELLABLE_ITEMS_EMPTY.getText(), buttons)); 41 | } 42 | 43 | @Override 44 | public void selectItem(SellableItem item) { 45 | new ManageSellableItemController(manager, item).showScreen(); 46 | } 47 | 48 | private void addItem() { 49 | new AddSellableItemController(manager, shop).showScreen(); 50 | } 51 | 52 | @Override 53 | public Collection fetchItems() { 54 | return shop.sellableItems; 55 | } 56 | 57 | @Override 58 | public String getTitle() { 59 | // TODO: check divided permissions 60 | return manager.getPlayer().hasPermission("shop.edit") 61 | ? Message.MENU_EDIT_SELL_LIST.getText() 62 | : Message.WDW_BROWSE_SELLABLE_ITEMS_TITLE.getText(); 63 | } 64 | 65 | @Override 66 | public String buildItemButtonText(SellableItem item) { 67 | Item gameItem = item.toGameItem(); 68 | 69 | String result = Message.BTN_ITEM_BUY.getText(item.getName(), 70 | item.getPrice(), Trading.getSettings().getCurrency()); 71 | 72 | if (gameItem.hasEnchantments()) { 73 | return TextFormat.colorize( 74 | "&" + TextFormat.DARK_PURPLE.getChar() + result 75 | + "&" + TextFormat.RESET.getChar()); 76 | } else return result; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/sell/edit/ManageSellableItemController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.sell.edit; 2 | 3 | import ua.leonidius.trdinterface.controllers.DeleteItemController; 4 | import ua.leonidius.trdinterface.controllers.EditItemController; 5 | import ua.leonidius.trdinterface.controllers.ItemDetailsViewController; 6 | import ua.leonidius.trdinterface.controllers.ManageEnchantmentsController; 7 | import ua.leonidius.trdinterface.models.SellableItem; 8 | import ua.leonidius.trdinterface.views.ScreenManager; 9 | import ua.leonidius.trdinterface.views.screens.sell.edit.ManageSellableItemScreen; 10 | 11 | public class ManageSellableItemController extends ItemDetailsViewController { 12 | 13 | private final SellableItem item; 14 | 15 | public ManageSellableItemController(ScreenManager manager, SellableItem item) { 16 | super(manager); 17 | this.item = item; 18 | } 19 | 20 | @Override 21 | public void showScreen() { 22 | manager.addAndShow(new ManageSellableItemScreen(this)); 23 | } 24 | 25 | public boolean showEditingButtons() { 26 | // TODO: check divided permissions 27 | return manager.getPlayer().hasPermission("shop.edit"); 28 | } 29 | 30 | @Override 31 | protected SellableItem getItem() { 32 | return item; 33 | } 34 | 35 | public void editItem() { 36 | new EditItemController(manager, item).showScreen(); 37 | } 38 | 39 | public void manageEnchantments() { 40 | new ManageEnchantmentsController(manager, item).showScreen(); 41 | } 42 | 43 | public void deleteItem() { 44 | new DeleteItemController(manager, item).showScreen(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/translations/AddTranslationController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.translations; 2 | 3 | import cn.nukkit.item.Item; 4 | import com.j256.ormlite.dao.Dao; 5 | import com.j256.ormlite.dao.DaoManager; 6 | import ua.leonidius.trdinterface.Message; 7 | import ua.leonidius.trdinterface.Trading; 8 | import ua.leonidius.trdinterface.controllers.BaseController; 9 | import ua.leonidius.trdinterface.models.Translation; 10 | import ua.leonidius.trdinterface.views.ScreenManager; 11 | import ua.leonidius.trdinterface.views.screens.translations.AddTranslationScreen; 12 | 13 | import java.sql.SQLException; 14 | 15 | public class AddTranslationController extends BaseController { 16 | 17 | public AddTranslationController(ScreenManager manager) { 18 | super(manager); 19 | } 20 | 21 | @Override 22 | public void showScreen() { 23 | manager.addAndShow(new AddTranslationScreen(this), true); 24 | } 25 | 26 | public void submitInput(String itemId, String translation) { 27 | Item gameItem; 28 | if (itemId.isEmpty() || translation.isEmpty() 29 | || (gameItem = Item.fromString(itemId)).getId() == 0) { 30 | showErrorScreen(Message.WDW_INVALID_PARAMS.getText()); 31 | return; 32 | } 33 | 34 | try { 35 | Dao translationDao = 36 | DaoManager.createDao(Trading.getSource(), Translation.class); 37 | if (translationDao.queryForEq("item_id", itemId).size() != 0) { 38 | showErrorScreen(Message.WDW_ADD_CUSTOM_NAME_FAIL.getText()); 39 | return; 40 | } 41 | 42 | Translation translationModel = new Translation(itemId, translation); 43 | translationDao.create(translationModel); 44 | 45 | if (Trading.getSettings().logEdits()) { 46 | Message.LOG_TRANSLATION_ADDED.log(manager.getPlayer().getName(), 47 | gameItem.getName(), itemId, translation); 48 | } 49 | } catch (SQLException e) { 50 | handleException(e); 51 | return; 52 | } 53 | 54 | manager.back(); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/translations/DeleteTranslationController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.translations; 2 | 3 | import cn.nukkit.item.Item; 4 | import com.j256.ormlite.dao.Dao; 5 | import com.j256.ormlite.dao.DaoManager; 6 | import ua.leonidius.trdinterface.Message; 7 | import ua.leonidius.trdinterface.Trading; 8 | import ua.leonidius.trdinterface.controllers.ModalController; 9 | import ua.leonidius.trdinterface.models.Translation; 10 | import ua.leonidius.trdinterface.views.ScreenManager; 11 | import ua.leonidius.trdinterface.views.screens.ModalScreen; 12 | 13 | import java.sql.SQLException; 14 | 15 | public class DeleteTranslationController extends ModalController { 16 | 17 | private final Translation translation; 18 | 19 | public DeleteTranslationController(ScreenManager manager, Translation translation) { 20 | super(manager); 21 | this.translation = translation; 22 | } 23 | 24 | @Override 25 | public void showScreen() { 26 | manager.addAndShow(new ModalScreen( 27 | Message.WDW_DELETE_CUSTOM_NAME_TITLE.getText(), 28 | Message.WDW_DELETE_CUSTOM_NAME_CONF.getText(), 29 | this), true); 30 | } 31 | 32 | @Override 33 | public void onPositiveResponse() { 34 | try { 35 | Dao translationDao = 36 | DaoManager.createDao(Trading.getSource(), Translation.class); 37 | 38 | translationDao.delete(translation); 39 | 40 | if (Trading.getSettings().logEdits()) { 41 | Message.LOG_TRANSLATION_DELETED.log(manager.getPlayer().getName(), 42 | Item.fromString(translation.getItemId()).getName(), 43 | translation.getItemId()); 44 | } 45 | 46 | manager.backTwoScreens(); 47 | } catch (SQLException e) { 48 | handleException(e); 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/translations/EditTranslationController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.translations; 2 | 3 | import cn.nukkit.item.Item; 4 | import com.j256.ormlite.dao.Dao; 5 | import com.j256.ormlite.dao.DaoManager; 6 | import ua.leonidius.trdinterface.Message; 7 | import ua.leonidius.trdinterface.Trading; 8 | import ua.leonidius.trdinterface.controllers.NamingController; 9 | import ua.leonidius.trdinterface.models.Translation; 10 | import ua.leonidius.trdinterface.views.ScreenManager; 11 | import ua.leonidius.trdinterface.views.screens.NamingScreen; 12 | 13 | import java.sql.SQLException; 14 | 15 | public class EditTranslationController extends NamingController { 16 | 17 | private final Translation translation; 18 | 19 | public EditTranslationController(ScreenManager manager, Translation translation) { 20 | super(manager); 21 | this.translation = translation; 22 | } 23 | 24 | @Override 25 | protected String getScreenTitle() { 26 | return Message.WDW_EDIT_CUSTOM_NAME_TITLE.getText(); 27 | } 28 | 29 | @Override 30 | protected String getInputFieldHint() { 31 | return Message.WDW_CUSTOM_NAME_HINT.getText(); 32 | } 33 | 34 | @Override 35 | public void showScreen() { 36 | manager.addAndShow(new NamingScreen(this, getScreenTitle(), 37 | getInputFieldHint(), translation.getTranslation()), true); 38 | } 39 | 40 | @Override 41 | public void submitName(String newTranslation) { 42 | String oldTranslation = translation.getTranslation(); 43 | 44 | if (newTranslation.equals(oldTranslation)) { 45 | manager.back(); 46 | return; 47 | } 48 | 49 | translation.setTranslation(newTranslation); 50 | 51 | try { 52 | Dao translationDao = 53 | DaoManager.createDao(Trading.getSource(), Translation.class); 54 | 55 | translationDao.update(translation); 56 | 57 | if (Trading.getSettings().logEdits()) { 58 | Message.LOG_TRANSLATION_CHANGED.log(manager.getPlayer().getName(), 59 | Item.fromString(translation.getItemId()).getName(), 60 | translation.getItemId(), oldTranslation, newTranslation); 61 | } 62 | 63 | manager.back(); 64 | } catch (SQLException e) { 65 | handleException(e); 66 | } 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/translations/TranslationMenuController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.translations; 2 | 3 | import cn.nukkit.item.Item; 4 | import ua.leonidius.trdinterface.Message; 5 | import ua.leonidius.trdinterface.controllers.BaseController; 6 | import ua.leonidius.trdinterface.models.Translation; 7 | import ua.leonidius.trdinterface.views.ScreenManager; 8 | import ua.leonidius.trdinterface.views.screens.translations.CustomNameMenuScreen; 9 | 10 | public class TranslationMenuController extends BaseController { 11 | 12 | private final Translation translation; 13 | 14 | public TranslationMenuController(ScreenManager manager, Translation translation) { 15 | super(manager); 16 | this.translation = translation; 17 | } 18 | 19 | @Override 20 | public void showScreen() { 21 | manager.addAndShow(new CustomNameMenuScreen(this)); 22 | } 23 | 24 | public String getContent() { 25 | return Message.WDW_CUSTOM_NAME_INFO.getText(translation.getItemId(), 26 | Item.fromString(translation.getItemId()).getName(), 27 | translation.getTranslation()); 28 | } 29 | 30 | public void editTranslation() { 31 | new EditTranslationController(manager, translation).showScreen(); 32 | } 33 | 34 | public void deleteTranslation() { 35 | new DeleteTranslationController(manager, translation).showScreen(); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/controllers/translations/TranslationsListController.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.controllers.translations; 2 | 3 | import cn.nukkit.item.Item; 4 | import com.j256.ormlite.dao.Dao; 5 | import com.j256.ormlite.dao.DaoManager; 6 | import ua.leonidius.trdinterface.Message; 7 | import ua.leonidius.trdinterface.Trading; 8 | import ua.leonidius.trdinterface.controllers.ListController; 9 | import ua.leonidius.trdinterface.models.Translation; 10 | import ua.leonidius.trdinterface.views.ScreenManager; 11 | import ua.leonidius.trdinterface.views.screens.ListScreen; 12 | 13 | import java.sql.SQLException; 14 | import java.util.Collection; 15 | import java.util.LinkedHashMap; 16 | 17 | /** 18 | * Controller for the list of custom item translations. 19 | * The list is accessed from the main menu. 20 | */ 21 | public class TranslationsListController extends ListController { 22 | 23 | ListScreen screen; 24 | 25 | public TranslationsListController(ScreenManager manager) { 26 | super(manager); 27 | } 28 | 29 | @Override 30 | public void showScreen() { 31 | LinkedHashMap buttons = 32 | new LinkedHashMap<>(); 33 | buttons.put(Message.BTN_ADD_CUSTOM_NAME.getText(), this::addTranslation); 34 | manager.addAndShow(screen = new ListScreen<>(this, 35 | Message.WDW_CUSTOM_NAMES_HINT.getText(), 36 | Message.WDW_CUSTOM_NAMES_HINT.getText(), buttons)); 37 | } 38 | 39 | @Override 40 | public Collection fetchItems() { 41 | try { 42 | Dao translationDao = 43 | DaoManager.createDao(Trading.getSource(), Translation.class); 44 | return translationDao.queryForAll(); 45 | } catch (SQLException e) { 46 | Trading.printException(e); 47 | screen.setContent(screen.getContent() + '\n' + Message.ERROR.getText()); 48 | return null; 49 | } 50 | 51 | } 52 | 53 | @Override 54 | public void selectItem(Translation translation) { 55 | new TranslationMenuController(manager, translation).showScreen(); 56 | } 57 | 58 | @Override 59 | public String buildItemButtonText(Translation translation) { 60 | return Item.fromString(translation.getItemId()).getName() 61 | + " (" + translation.getItemId() + ")" 62 | + " - " + translation.getTranslation(); 63 | } 64 | 65 | @Override 66 | public String getTitle() { 67 | return Message.MENU_CUSTOM_NAMES.getText(); 68 | } 69 | 70 | private void addTranslation() { 71 | new AddTranslationController(manager).showScreen(); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/models/BuyableItem.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.models; 2 | 3 | import com.j256.ormlite.dao.Dao; 4 | import com.j256.ormlite.dao.DaoManager; 5 | import com.j256.ormlite.dao.ForeignCollection; 6 | import com.j256.ormlite.field.DataType; 7 | import com.j256.ormlite.field.DatabaseField; 8 | import com.j256.ormlite.field.ForeignCollectionField; 9 | import com.j256.ormlite.table.DatabaseTable; 10 | import ua.leonidius.trdinterface.Trading; 11 | 12 | import java.io.IOException; 13 | import java.sql.SQLException; 14 | 15 | @DatabaseTable(tableName = "buyable_items") 16 | public class BuyableItem extends ShopItem { 17 | 18 | public BuyableItem() {} 19 | 20 | public BuyableItem(Shop shop, Category category, String itemId, double price) { 21 | this.shop = shop; 22 | this.category = category; 23 | this.itemId = itemId; 24 | this.price = price; 25 | } 26 | 27 | @DatabaseField(generatedId = true, columnName = "record_id") 28 | private int recordId; 29 | 30 | @DatabaseField(canBeNull = false, foreign = true, columnName = "shop_id") 31 | private Shop shop; 32 | 33 | @DatabaseField(canBeNull = false, foreign = true, columnName = "category_id") 34 | private Category category; 35 | 36 | @DatabaseField(canBeNull = false, columnName = "item_id") 37 | private String itemId; 38 | 39 | @DatabaseField(canBeNull = false) 40 | private double price; 41 | 42 | @DatabaseField(dataType = DataType.BYTE_ARRAY) 43 | private byte[] nbt; 44 | 45 | @ForeignCollectionField(columnName = "discounts", foreignFieldName = "item", 46 | eager = true) 47 | private ForeignCollection discount; 48 | 49 | @Override 50 | protected int getRecordId() { 51 | return recordId; 52 | } 53 | 54 | @Override 55 | public String getItemId() { 56 | return itemId; 57 | } 58 | 59 | @Override 60 | public double getPrice() { 61 | if (getDiscount() == null) return price; 62 | return price - (price * (getDiscount().getPercent() / 100)); 63 | } 64 | 65 | @Override 66 | public double getPurePrice() { 67 | return price; 68 | } 69 | 70 | public double getOriginalPrice() { 71 | return price; 72 | } 73 | 74 | @Override 75 | public byte[] getNbt() { 76 | return nbt; 77 | } 78 | 79 | /** 80 | * @return discount for the item if there is one, null otherwise 81 | */ 82 | public Discount getDiscount() { 83 | if (discount.size() == 0) return null; 84 | Discount result = discount.iterator().next(); 85 | try { 86 | discount.closeLastIterator(); 87 | } catch (IOException e) { 88 | Trading.printException(e); 89 | } 90 | return result; 91 | } 92 | 93 | public void removeDiscount() { 94 | Discount d = getDiscount(); 95 | if (d == null) return; 96 | discount.remove(d); 97 | } 98 | 99 | public void addDiscount(Discount d) { 100 | discount.add(d); 101 | } 102 | 103 | @Override 104 | public void setItemId(String itemId) { 105 | this.itemId = itemId; 106 | } 107 | 108 | @Override 109 | public void setPrice(double price) { 110 | this.price = price; 111 | } 112 | 113 | @Override 114 | public void setNbt(byte[] nbt) { 115 | this.nbt = nbt; 116 | } 117 | 118 | @Override 119 | public void setShop(Shop shop) { 120 | this.shop = shop; 121 | } 122 | 123 | public void setCategory(Category category) { 124 | this.category = category; 125 | } 126 | 127 | @Override 128 | public void update() throws SQLException { 129 | Dao itemDao = 130 | DaoManager.createDao(Trading.getSource(), BuyableItem.class); 131 | itemDao.update(this); 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/models/Category.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.models; 2 | 3 | import com.j256.ormlite.dao.ForeignCollection; 4 | import com.j256.ormlite.field.DatabaseField; 5 | import com.j256.ormlite.field.ForeignCollectionField; 6 | import com.j256.ormlite.table.DatabaseTable; 7 | 8 | /** 9 | * Domain model for a category of buyable items 10 | */ 11 | @DatabaseTable(tableName = "categories") 12 | public class Category { 13 | 14 | public Category() {} 15 | 16 | public Category(Shop shop, String name) { 17 | this.shop = shop; 18 | this.name = name; 19 | } 20 | 21 | @DatabaseField(generatedId = true, columnName = "record_id") 22 | private int recordId; // primary key, not null 23 | 24 | @DatabaseField(canBeNull = false, foreign = true, columnName = "shop_id") 25 | private Shop shop; // must be refreshed before accessing anything other than ID 26 | // 'foreignAutoRefresh = true' can be set if needed 27 | 28 | @DatabaseField(canBeNull = false, unique = true) 29 | private String name; 30 | 31 | @ForeignCollectionField(foreignFieldName = "category") 32 | public ForeignCollection items; 33 | 34 | public String getName() { 35 | return name; 36 | } 37 | 38 | public void setName(String name) { 39 | this.name = name; 40 | } 41 | 42 | public Shop getShop() { 43 | return shop; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/models/Discount.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.models; 2 | 3 | import com.j256.ormlite.field.DatabaseField; 4 | import com.j256.ormlite.table.DatabaseTable; 5 | 6 | @DatabaseTable(tableName = "discounts") 7 | public class Discount { 8 | 9 | public Discount() { 10 | } 11 | 12 | public Discount(BuyableItem item, double percent, long endTime) { 13 | this.item = item; 14 | this.percent = percent; 15 | this.endTime = endTime; 16 | } 17 | 18 | @DatabaseField(generatedId = true, columnName = "record_id") 19 | private int recordId; 20 | 21 | @DatabaseField(canBeNull = false, foreign = true, unique = true) 22 | private BuyableItem item; 23 | 24 | @DatabaseField(canBeNull = false) 25 | private double percent; 26 | 27 | @DatabaseField(canBeNull = false, columnName = "end_time") 28 | private long endTime; // seconds since 01/01/1970 29 | 30 | public double getPercent() { 31 | return percent; 32 | } 33 | 34 | public long getEndTime() { 35 | return endTime; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/models/SellableItem.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.models; 2 | 3 | import com.j256.ormlite.dao.Dao; 4 | import com.j256.ormlite.dao.DaoManager; 5 | import com.j256.ormlite.field.DataType; 6 | import com.j256.ormlite.field.DatabaseField; 7 | import com.j256.ormlite.table.DatabaseTable; 8 | import ua.leonidius.trdinterface.Trading; 9 | 10 | import java.sql.SQLException; 11 | 12 | @DatabaseTable(tableName = "sellable_items") 13 | public class SellableItem extends ShopItem { 14 | 15 | public SellableItem() { 16 | } 17 | 18 | public SellableItem(Shop shop, String itemId, double price) { 19 | this.shop = shop; 20 | this.itemId = itemId; 21 | this.price = price; 22 | } 23 | 24 | @DatabaseField(generatedId = true, columnName = "record_id") 25 | private int recordId; 26 | 27 | @DatabaseField(canBeNull = false, foreign = true, columnName = "shop_id") 28 | Shop shop; 29 | 30 | @DatabaseField(canBeNull = false, columnName = "item_id") 31 | private String itemId; 32 | 33 | @DatabaseField(canBeNull = false) 34 | private double price; 35 | 36 | @DatabaseField(dataType = DataType.BYTE_ARRAY) 37 | private byte[] nbt; 38 | 39 | @Override 40 | protected int getRecordId() { 41 | return recordId; 42 | } 43 | 44 | @Override 45 | public String getItemId() { 46 | return itemId; 47 | } 48 | 49 | @Override 50 | public double getPrice() { 51 | return price; 52 | } 53 | 54 | @Override 55 | public double getPurePrice() { 56 | return price; 57 | } 58 | 59 | @Override 60 | public byte[] getNbt() { 61 | return nbt; 62 | } 63 | 64 | @Override 65 | public void setItemId(String itemId) { 66 | this.itemId = itemId; 67 | } 68 | 69 | @Override 70 | public void setPrice(double price) { 71 | this.price = price; 72 | } 73 | 74 | @Override 75 | public void setNbt(byte[] nbt) { 76 | this.nbt = nbt; 77 | } 78 | 79 | @Override 80 | public void setShop(Shop shop) { 81 | this.shop = shop; 82 | } 83 | 84 | // TODO: remove this method 85 | @Override 86 | public void update() throws SQLException { 87 | Dao itemDao = 88 | DaoManager.createDao(Trading.getSource(), SellableItem.class); 89 | itemDao.update(this); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/models/Shop.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.models; 2 | 3 | import com.j256.ormlite.dao.ForeignCollection; 4 | import com.j256.ormlite.field.DatabaseField; 5 | import com.j256.ormlite.field.ForeignCollectionField; 6 | import com.j256.ormlite.table.DatabaseTable; 7 | 8 | /** 9 | * Domain model for a shop 10 | */ 11 | @DatabaseTable(tableName = "shops") 12 | public class Shop { 13 | 14 | public Shop() {} 15 | 16 | public Shop(String name) { 17 | this.name = name; 18 | } 19 | 20 | public static Shop getDefault() { 21 | Shop defaultShop = new Shop("default"); 22 | defaultShop.recordId = 1; 23 | return defaultShop; 24 | } 25 | 26 | @DatabaseField(generatedId = true, columnName = "record_id") 27 | int recordId; 28 | 29 | @DatabaseField(canBeNull = false, unique = true) 30 | String name; 31 | 32 | @ForeignCollectionField(columnName = "buyable_items_categories", foreignFieldName = "shop") 33 | public ForeignCollection buyableItemsCategories; 34 | // Do we need columnName here? 35 | 36 | @ForeignCollectionField(columnName = "sellable_items", foreignFieldName = "shop") 37 | public ForeignCollection sellableItems; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/models/ShopItem.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.models; 2 | 3 | import cn.nukkit.item.Item; 4 | import cn.nukkit.item.enchantment.Enchantment; 5 | import cn.nukkit.nbt.NBTIO; 6 | import cn.nukkit.nbt.tag.CompoundTag; 7 | import com.j256.ormlite.dao.Dao; 8 | import com.j256.ormlite.dao.DaoManager; 9 | import ua.leonidius.trdinterface.Message; 10 | import ua.leonidius.trdinterface.Trading; 11 | 12 | import java.io.IOException; 13 | import java.sql.SQLException; 14 | import java.util.List; 15 | 16 | public abstract class ShopItem { 17 | 18 | protected abstract int getRecordId(); 19 | 20 | public abstract String getItemId(); 21 | 22 | /** 23 | * @return price with discount (if there is a discount) 24 | */ 25 | public abstract double getPrice(); 26 | 27 | /** 28 | * @return price without discount 29 | */ 30 | public abstract double getPurePrice(); 31 | 32 | public abstract byte[] getNbt(); 33 | 34 | public abstract void setItemId(String itemId); 35 | 36 | public abstract void setPrice(double price); 37 | 38 | public abstract void setNbt(byte[] nbt); 39 | 40 | public abstract void setShop(Shop shop); 41 | 42 | /** 43 | * Used to cache game item for optimization 44 | */ 45 | private Item gameItem = null; 46 | 47 | public Item toGameItem() { 48 | if (gameItem != null) return gameItem; 49 | 50 | Item item = Item.fromString(getItemId()); 51 | if (getNbt() != null) { 52 | try { 53 | CompoundTag tag = NBTIO.read(getNbt()); 54 | item.setCompoundTag(tag); 55 | } catch (IOException e) { 56 | Message.LOG_READING_NBT_FAILED.error(getRecordId()); 57 | Trading.printException(e); 58 | } 59 | } 60 | 61 | return gameItem = item; 62 | } 63 | 64 | /** 65 | * Deleting the cached version of game item 66 | * Used when after a change in an item we need 67 | * to update its description in ManageBuyableItemScreen 68 | */ 69 | public void resetGameItem() { 70 | gameItem = null; 71 | } 72 | 73 | public static void populate(T item, String itemId, String priceS, 74 | String customName, String customLore) { 75 | populate(item, itemId, priceS, customName, customLore, new Enchantment[0]); 76 | } 77 | 78 | /** 79 | * Used to populate the model with item_id, price and nbt 80 | * This method doesn't change shop and category (they 81 | * have to be populated separately) 82 | * 83 | * @param item item to populate 84 | * @param BuyableItem or SellableItem 85 | */ 86 | public static void populate(T item, String itemId, String priceS, 87 | String customName, String customLore, 88 | Enchantment[] enchantments) 89 | throws IllegalArgumentException { 90 | Item gameItem; 91 | 92 | if (itemId.isEmpty()) { 93 | throw new IllegalArgumentException( 94 | Message.WDW_ADD_ITEM_MISSING_ID.getText()); 95 | } 96 | 97 | if ((gameItem = Item.fromString(itemId)).getId() == 0) { 98 | throw new IllegalArgumentException( 99 | Message.WDW_ADD_ITEM_INVALID_ID.getText()); 100 | } 101 | 102 | double price; 103 | try { 104 | price = Double.parseDouble(priceS.replace(",", ".")); 105 | } catch (NumberFormatException e) { 106 | throw new IllegalArgumentException( 107 | Message.WDW_ADD_ITEM_INVALID_PRICE.getText()); 108 | } 109 | if (price < 0) { 110 | throw new IllegalArgumentException( 111 | Message.WDW_EDIT_ITEM_NEGATIVE_PRICE.getText()); 112 | } 113 | 114 | if (customName != null && !customName.isEmpty()) 115 | gameItem.setCustomName(customName); 116 | 117 | if (customLore != null && !customLore.isEmpty()) 118 | gameItem.setLore(customLore.split("\n")); 119 | 120 | if (enchantments != null && enchantments.length != 0) 121 | gameItem.addEnchantment(enchantments); 122 | 123 | item.setItemId(itemId); 124 | item.setPrice(price); 125 | 126 | try { 127 | item.setNbt(gameItem.getNamedTag() == null ? null 128 | : NBTIO.write(gameItem.getNamedTag())); 129 | } catch (IOException e) { 130 | Trading.printException(e); 131 | throw new IllegalArgumentException( 132 | Message.WDW_ADD_ITEM_INVALID_NBT.getText()); 133 | } 134 | } 135 | 136 | /** 137 | * Used to cache the item's original name 138 | * (= not a custom name, like the one added 139 | * with an anvil) to avoid querying for custom 140 | * translation more than once 141 | */ 142 | private String name = null; 143 | 144 | /** 145 | * Returns the name of the item, which my be a custom name 146 | * or a custom translation 147 | * 148 | * @return name of the item 149 | */ 150 | public String getName() { 151 | if (toGameItem().hasCustomName()) 152 | return toGameItem().getCustomName(); 153 | return getOriginalName(); 154 | } 155 | 156 | /** 157 | * Returns the name of an item, which may have a custom translation 158 | * 159 | * @return original name 160 | */ 161 | public String getOriginalName() { 162 | if (name == null) { 163 | try { 164 | Dao translationDao = 165 | DaoManager.createDao(Trading.getSource(), Translation.class); 166 | 167 | List list = 168 | translationDao.queryForEq("item_id", getItemId()); 169 | 170 | if (list.size() != 0) { 171 | name = list.get(0).getTranslation(); 172 | } else name = Item.fromString(getItemId()).getName(); 173 | } catch (SQLException e) { 174 | Trading.printException(e); 175 | name = Item.fromString(getItemId()).getName(); 176 | } 177 | } 178 | return name; 179 | } 180 | 181 | public abstract void update() throws SQLException; 182 | 183 | } 184 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/models/Translation.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.models; 2 | 3 | import com.j256.ormlite.field.DatabaseField; 4 | import com.j256.ormlite.table.DatabaseTable; 5 | 6 | /** 7 | * A model for custom item name translations 8 | */ 9 | @DatabaseTable(tableName = "translations") 10 | public class Translation { 11 | 12 | public Translation() { 13 | } 14 | 15 | public Translation(String itemId, String translation) { 16 | this.itemId = itemId; 17 | this.translation = translation; 18 | } 19 | 20 | @DatabaseField(generatedId = true, columnName = "record_id") 21 | private int recordId; 22 | 23 | @DatabaseField(canBeNull = false, columnName = "item_id") 24 | private String itemId; 25 | 26 | @DatabaseField(canBeNull = false, columnName = "translation") 27 | private String translation; 28 | 29 | public String getItemId() { 30 | return itemId; 31 | } 32 | 33 | public String getTranslation() { 34 | return translation; 35 | } 36 | 37 | public void setTranslation(String translation) { 38 | this.translation = translation; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/utils/EnchantmentWrapper.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.utils; 2 | 3 | import cn.nukkit.item.Item; 4 | import cn.nukkit.item.enchantment.Enchantment; 5 | 6 | public class EnchantmentWrapper { 7 | 8 | private final Enchantment enchantment; 9 | 10 | public EnchantmentWrapper(Enchantment enchantment) { 11 | this.enchantment = enchantment; 12 | } 13 | 14 | public Enchantment getEnchantment() { 15 | return enchantment; 16 | } 17 | 18 | public String getName() { 19 | return enchantment.getName() + " " + enchantment.getLevel(); 20 | } 21 | 22 | @Override 23 | public boolean equals(Object o) { 24 | if (this == o) return true; 25 | if (!(o instanceof EnchantmentWrapper)) return false; 26 | EnchantmentWrapper that = (EnchantmentWrapper) o; 27 | return enchantment.getId() == that.enchantment.getId() && 28 | enchantment.getLevel() == that.enchantment.getLevel(); 29 | } 30 | 31 | public static EnchantmentWrapper[] getWrappers(Item item) { 32 | Enchantment[] enchantments = item.getEnchantments(); 33 | EnchantmentWrapper[] wrappers = new EnchantmentWrapper[enchantments.length]; 34 | for (int i = 0; i < enchantments.length; i++) { 35 | wrappers[i] = new EnchantmentWrapper(enchantments[i]); 36 | } 37 | return wrappers; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/utils/ItemCompare.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.utils; 2 | 3 | import cn.nukkit.item.Item; 4 | 5 | import java.util.Arrays; 6 | 7 | public abstract class ItemCompare { 8 | 9 | /** 10 | * Comparing two items for equality taking custom names, lores 11 | * and enchantments into account, but not their count 12 | * 13 | * @param item1 first item 14 | * @param item2 second item 15 | * @return whether the two items are equal or not 16 | */ 17 | public static boolean equals(Item item1, Item item2) { 18 | boolean initialTest = item1.getId() == item2.getId() 19 | && item1.getDamage() == item2.getDamage() 20 | && item1.getCustomName().equals(item2.getCustomName()) 21 | && Arrays.equals(item1.getLore(), item2.getLore()); 22 | if (!initialTest) return false; 23 | 24 | EnchantmentWrapper[] wrappers1 = EnchantmentWrapper.getWrappers(item1); 25 | EnchantmentWrapper[] wrappers2 = EnchantmentWrapper.getWrappers(item2); 26 | 27 | if (wrappers1 == wrappers2) return true; 28 | 29 | if (wrappers1.length != wrappers2.length) return false; 30 | 31 | for (EnchantmentWrapper w1 : wrappers1) { 32 | boolean secondArrayContains = false; 33 | for (EnchantmentWrapper w2 : wrappers2) { 34 | if (w1.equals(w2)) { 35 | secondArrayContains = true; 36 | break; 37 | } 38 | } 39 | if (!secondArrayContains) { 40 | return false; 41 | } 42 | } 43 | 44 | return true; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/utils/TimeUnit.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.utils; 2 | 3 | import ua.leonidius.trdinterface.Message; 4 | 5 | public enum TimeUnit { 6 | 7 | MINUTES(60, Message.MINUTES.getText()), 8 | HOURS(60 * 60, Message.HOURS.getText()), 9 | DAYS(24 * 60 * 60, Message.DAYS.getText()), 10 | MONTHS(30 * 24 * 60 * 60, Message.MONTHS.getText()); 11 | 12 | /** 13 | * time, measured in the unit * multiplier = time in seconds 14 | */ 15 | private final long multiplier; 16 | 17 | private final String name; 18 | 19 | TimeUnit(long multiplier, String name) { 20 | this.multiplier = multiplier; 21 | this.name = name; 22 | } 23 | 24 | public long getMultiplier() { 25 | return multiplier; 26 | } 27 | 28 | public String getName() { 29 | return name; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/utils/YamlToDbConverter.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.utils; 2 | 3 | import cn.nukkit.item.Item; 4 | import cn.nukkit.utils.Config; 5 | import cn.nukkit.utils.ConfigSection; 6 | import com.j256.ormlite.dao.Dao; 7 | import com.j256.ormlite.dao.DaoManager; 8 | import ua.leonidius.trdinterface.Message; 9 | import ua.leonidius.trdinterface.Trading; 10 | import ua.leonidius.trdinterface.models.*; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | * Contains methods to add items from the old 16 | * YAML item lists to the new database, as 17 | * well as import custom item name translations 18 | */ 19 | public abstract class YamlToDbConverter { 20 | 21 | /** 22 | * Converts the list of buyable items from 23 | * YAML config format to database format 24 | * 25 | * @param buyableItems config to convert 26 | * @return whether buyList.yml can be safely deleted 27 | * without losing data 28 | */ 29 | public static boolean convertBuyableItems(Config buyableItems) { 30 | try { 31 | Dao categoryDao = 32 | DaoManager.createDao(Trading.getSource(), Category.class); 33 | 34 | int numberOfCategories = 0; 35 | int numberOfItems = 0; 36 | 37 | for (String categoryKey : buyableItems.getKeys(false)) { 38 | ConfigSection category = buyableItems.getSection(categoryKey); 39 | 40 | String categoryName = category.getString("name"); 41 | 42 | Category categoryModel; 43 | List eponymousCategories = 44 | categoryDao.queryForEq("name", categoryName); 45 | if (eponymousCategories.size() == 0) { 46 | categoryModel = new Category(Shop.getDefault(), categoryName); 47 | categoryDao.create(categoryModel); 48 | numberOfCategories++; 49 | } else categoryModel = eponymousCategories.get(0); 50 | 51 | categoryDao.assignEmptyForeignCollection(categoryModel, "items"); 52 | 53 | for (String itemKey : category.getSection("items").getKeys(false)) { 54 | ConfigSection item = category.getSection("items").getSection(itemKey); 55 | 56 | String id = itemKey.replace("-", ":"); 57 | if (Item.fromString(id).getId() == 0) continue; 58 | double price = item.getDouble("price"); 59 | 60 | BuyableItem itemModel = new BuyableItem(Shop.getDefault(), 61 | categoryModel, id, price); 62 | 63 | categoryModel.items.add(itemModel); 64 | 65 | numberOfItems++; 66 | 67 | categoryModel.items.getDao() 68 | .assignEmptyForeignCollection(itemModel, "discounts"); 69 | 70 | if (item.exists("discount")) { 71 | double percent = item.getDouble("discount"); 72 | Discount discount = new Discount(itemModel, percent, -1); // infinite 73 | itemModel.addDiscount(discount); 74 | } 75 | } 76 | } 77 | 78 | Message.LOG_BUYABLE_ITEMS_IMPORTED.log(numberOfCategories, numberOfItems); 79 | 80 | return true; 81 | } catch (Exception e) { // return false in case of any exception 82 | // so that buyList.yml doesn't get deleted 83 | Trading.printException(e); 84 | return false; 85 | } 86 | } 87 | 88 | /** 89 | * Converts the list of sellable items from 90 | * YAML config format to database format 91 | * 92 | * @param sellableItems config to convert 93 | * @return whether sellList.yml can be safely deleted 94 | * without losing data 95 | */ 96 | public static boolean convertSellableItems(Config sellableItems) { 97 | try { 98 | int numberOfItems = 0; 99 | 100 | for (String itemKey : sellableItems.getKeys(false)) { 101 | String itemId = itemKey.replace("-", ":"); 102 | double price = sellableItems.getDouble(itemKey); 103 | 104 | SellableItem itemModel = 105 | new SellableItem(Shop.getDefault(), itemId, price); 106 | 107 | Dao itemDao = 108 | DaoManager.createDao(Trading.getSource(), SellableItem.class); 109 | itemDao.create(itemModel); 110 | 111 | numberOfItems++; 112 | } 113 | 114 | Message.LOG_SELLABLE_ITEMS_IMPORTED.log(numberOfItems); 115 | 116 | return true; 117 | } catch (Exception e) { 118 | Trading.printException(e); 119 | return false; 120 | } 121 | } 122 | 123 | /** 124 | * Converts custom item name translations from 125 | * YAML config format to database format 126 | * 127 | * @param translations config to convert 128 | * @return whether customItemNames.yml can be 129 | * safely deleted without losing data 130 | */ 131 | public static boolean convertTranslations(Config translations) { 132 | try { 133 | int importedTranslations = 0; 134 | int skippedTranslations = 0; 135 | 136 | for (String key : translations.getKeys(false)) { 137 | String itemId = key.replace("-", ":"); 138 | String translation = translations.getString(key); 139 | 140 | Dao translationDao = 141 | DaoManager.createDao(Trading.getSource(), Translation.class); 142 | 143 | // if there is already a translation - do not override it 144 | if (translationDao.queryForEq("item_id", itemId).size() != 0) { 145 | skippedTranslations++; 146 | continue; 147 | } 148 | 149 | Translation translationModel = new Translation(itemId, translation); 150 | translationDao.create(translationModel); 151 | 152 | translations.remove(key); 153 | 154 | importedTranslations++; 155 | } 156 | 157 | if (skippedTranslations == 0) { 158 | Message.LOG_ALL_TRANSLATIONS_IMPORTED.log(importedTranslations); 159 | return true; 160 | } else { 161 | Message.LOG_IMPORT_SKIPPED_TRANSLATIONS.log(importedTranslations, 162 | skippedTranslations); 163 | return false; 164 | } 165 | } catch (Exception e) { 166 | Trading.printException(e); 167 | return false; 168 | } 169 | } 170 | 171 | } 172 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/ScreenManager.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views; 2 | 3 | import cn.nukkit.Player; 4 | import cn.nukkit.form.window.FormWindow; 5 | import ua.leonidius.trdinterface.views.screens.Screen; 6 | 7 | import java.util.Stack; 8 | 9 | /** 10 | * Manages all the screens that are shown to a specific player. 11 | */ 12 | public class ScreenManager { 13 | 14 | private final Player player; 15 | private final Stack backStack; 16 | private Screen currentScreen; 17 | 18 | public ScreenManager(Player player) { 19 | this.player = player; 20 | backStack = new Stack<>(); 21 | } 22 | 23 | public void addAndShow(Screen screen) { 24 | addAndShow(screen, false); 25 | } 26 | 27 | /** 28 | * Adding a screen to ScreenManager and showing it to the player 29 | * 30 | * @param screen screen to show 31 | * @param ignoreStack if true, it wouldn't be possible to return to this 32 | * screen as it will not be saved in the back stack 33 | */ 34 | public void addAndShow(Screen screen, boolean ignoreStack) { 35 | if (currentScreen != null && !currentScreen.ignoresStack()) { 36 | backStack.push(currentScreen); // saving current window 37 | } 38 | screen.update(); 39 | screen.setIgnoreStack(ignoreStack); 40 | currentScreen = screen; 41 | showScreen(player, screen); 42 | } 43 | 44 | public void back() { 45 | if (backStack.empty()) return; 46 | currentScreen = backStack.pop(); 47 | currentScreen.update(); 48 | showScreen(player, currentScreen); 49 | } 50 | 51 | public void backTwoScreens() { 52 | backStack.pop(); 53 | back(); 54 | } 55 | 56 | public Player getPlayer() { 57 | return player; 58 | } 59 | 60 | public void onClose() { 61 | backStack.clear(); // that's for JC to delete the screens 62 | } 63 | 64 | private void showScreen(Player player, Screen screen) { 65 | player.showFormWindow((FormWindow) screen); 66 | } 67 | 68 | } -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/elements/CallbackButton.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.elements; 2 | 3 | import cn.nukkit.form.element.ElementButton; 4 | 5 | public class CallbackButton extends ElementButton { 6 | 7 | private transient Callback callback; 8 | 9 | public CallbackButton(String text, Callback callback) { 10 | super(text); 11 | this.callback = callback; 12 | } 13 | 14 | public void setCallback(Callback callback) { 15 | this.callback = callback; 16 | } 17 | 18 | public void executeCallback() { 19 | callback.call(); 20 | } 21 | 22 | public interface Callback { 23 | void call(); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/screens/AmountSelectorScreen.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.screens; 2 | 3 | import cn.nukkit.event.player.PlayerFormRespondedEvent; 4 | import cn.nukkit.form.element.ElementLabel; 5 | import cn.nukkit.form.element.ElementSlider; 6 | import ua.leonidius.trdinterface.Message; 7 | import ua.leonidius.trdinterface.controllers.AmountSelectorController; 8 | 9 | public class AmountSelectorScreen extends CustomScreen { 10 | 11 | private final transient AmountSelectorController controller; 12 | 13 | public AmountSelectorScreen(AmountSelectorController controller, 14 | String title, String content, 15 | int maxAmount) { 16 | super(title); 17 | 18 | this.controller = controller; 19 | 20 | addElement(new ElementLabel(content)); 21 | addElement(new ElementLabel(Message.WDW_SELECT_ZERO_TO_RETURN.getText())); 22 | addElement(new ElementSlider(Message.WDW_BUY_AMOUNT.getText(), 0, maxAmount, 1, 1)); 23 | } 24 | 25 | @Override 26 | public void onResponse(PlayerFormRespondedEvent event) { 27 | int amount = (int)getResponse().getSliderResponse(2); 28 | if (amount == 0) controller.back(); 29 | else controller.selectAmount(amount); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/screens/CustomScreen.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.screens; 2 | 3 | import cn.nukkit.form.window.FormWindowCustom; 4 | 5 | public abstract class CustomScreen extends FormWindowCustom implements Screen { 6 | 7 | private transient boolean ignoresStack = false; 8 | 9 | public CustomScreen() { 10 | super(""); 11 | } 12 | 13 | public CustomScreen(String title) { 14 | super(title); 15 | } 16 | 17 | @Override 18 | public void setIgnoreStack(boolean ignoresStack) { 19 | this.ignoresStack = ignoresStack; 20 | } 21 | 22 | @Override 23 | public boolean ignoresStack() { 24 | return ignoresStack; 25 | } 26 | 27 | @Override 28 | public void update() { 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/screens/InfoScreen.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.screens; 2 | 3 | import ua.leonidius.trdinterface.Message; 4 | import ua.leonidius.trdinterface.controllers.InfoController; 5 | import ua.leonidius.trdinterface.views.elements.CallbackButton; 6 | 7 | /** 8 | * Universal success/error window that allows to go back to the previous window. 9 | */ 10 | public class InfoScreen extends SimpleScreen { 11 | 12 | public InfoScreen(InfoController controller, String title, String message) { 13 | super(title, message); 14 | addButton(new CallbackButton(Message.BTN_BACK.getText(), controller::back)); 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/screens/ItemDetailsEditScreen.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.screens; 2 | 3 | import cn.nukkit.event.player.PlayerFormRespondedEvent; 4 | import cn.nukkit.form.element.ElementInput; 5 | import cn.nukkit.form.element.ElementLabel; 6 | import ua.leonidius.trdinterface.Message; 7 | import ua.leonidius.trdinterface.controllers.ItemDetailsEditController; 8 | 9 | public class ItemDetailsEditScreen extends CustomScreen { 10 | 11 | private final transient ItemDetailsEditController controller; 12 | 13 | public ItemDetailsEditScreen(ItemDetailsEditController controller, String title) { 14 | this(controller, title, "", "", "", ""); 15 | } 16 | 17 | public ItemDetailsEditScreen(ItemDetailsEditController controller, String title, 18 | String itemId, String price, 19 | String customName, String customLore) { 20 | super(title); 21 | 22 | this.controller = controller; 23 | 24 | addElement(new ElementInput(Message.WDW_ADD_ITEM_ID.getText(), 25 | "", itemId)); // 0 26 | addElement(new ElementInput(Message.WDW_ADD_ITEM_PRICE.getText(), 27 | "", price)); // 1 28 | addElement(new ElementInput(Message.WDW_ADD_ITEM_CUSTOM_NAME.getText(), 29 | "", customName)); // 2 30 | addElement(new ElementInput(Message.WDW_ADD_ITEM_CUSTOM_LORE.getText(), 31 | "", customLore)); // 3 32 | addElement(new ElementLabel(Message.WDW_ADD_ITEM_ENCHANTMENTS.getText())); // 4 33 | } 34 | 35 | @Override 36 | public void onResponse(PlayerFormRespondedEvent event) { 37 | String itemId = getResponse().getInputResponse(0); 38 | String price = getResponse().getInputResponse(1); 39 | String customName = getResponse().getInputResponse(2); 40 | String customLore = getResponse().getInputResponse(3); 41 | controller.submitDetails(itemId, price, customName, customLore); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/screens/ListScreen.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.screens; 2 | 3 | import ua.leonidius.trdinterface.Message; 4 | import ua.leonidius.trdinterface.controllers.ListController; 5 | import ua.leonidius.trdinterface.views.elements.CallbackButton; 6 | 7 | import java.util.Collection; 8 | import java.util.Map; 9 | 10 | /** 11 | * A screen that allows to choose an item from a provided list of items, 12 | * and optionally shows extra action buttons on top of the list. 13 | * 14 | * @param represents the type of items in the list 15 | */ 16 | public class ListScreen extends SimpleScreen { 17 | 18 | private final transient ListController controller; 19 | private final transient String emptyContent; 20 | private final transient String notEmptyContent; 21 | private final transient Map additionalButtons; 22 | 23 | public ListScreen(ListController controller, 24 | String emptyContent, 25 | Map additionalButtons) { 26 | this(controller, emptyContent, "", additionalButtons); 27 | } 28 | 29 | /** 30 | * @param controller Controller for this screen 31 | * @param emptyContent Text to show if the list is empty 32 | * @param notEmptyContent Text to show if the list is not empty 33 | * @param additionalButtons Action buttons to show on top of the list 34 | */ 35 | public ListScreen(ListController controller, 36 | String emptyContent, String notEmptyContent, 37 | Map additionalButtons) { 38 | super(controller.getTitle()); 39 | this.controller = controller; 40 | this.emptyContent = emptyContent; 41 | this.notEmptyContent = notEmptyContent; 42 | this.additionalButtons = additionalButtons; 43 | } 44 | 45 | @Override 46 | public void update() { 47 | setTitle(controller.getTitle()); 48 | 49 | getButtons().clear(); 50 | 51 | // Back button 52 | addButton(new CallbackButton(Message.BTN_BACK.getText(), controller::back)); 53 | 54 | if (additionalButtons != null) { 55 | additionalButtons.forEach((String name, ButtonCallback action) -> 56 | addButton(new CallbackButton(name, action::call))); 57 | } 58 | 59 | Collection items = controller.fetchItems(); 60 | if (items == null) setContent(Message.ERROR.getText()); 61 | else if (items.isEmpty()) setContent(emptyContent); 62 | else { 63 | for (T item : items) { 64 | addButton(new CallbackButton(controller.buildItemButtonText(item), 65 | () -> controller.selectItem(item))); 66 | } 67 | setContent(notEmptyContent); 68 | } 69 | 70 | } 71 | 72 | public interface ButtonCallback { 73 | void call(); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/screens/MainScreen.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.screens; 2 | 3 | import ua.leonidius.trdinterface.Message; 4 | import ua.leonidius.trdinterface.controllers.MainController; 5 | import ua.leonidius.trdinterface.views.elements.CallbackButton; 6 | 7 | public class MainScreen extends SimpleScreen { 8 | 9 | public MainScreen(MainController controller) { 10 | super(Message.WDW_MAIN_TITLE.getText(), ""); 11 | 12 | addButton(new CallbackButton(Message.MENU_BUY.getText(), controller::buy)); 13 | addButton(new CallbackButton(Message.MENU_SELL.getText(), controller::sell)); 14 | 15 | if (controller.showCustomNamesButton()) { 16 | addButton(new CallbackButton(Message.MENU_CUSTOM_NAMES.getText(), 17 | controller::customNames)); 18 | } 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/screens/ModalScreen.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.screens; 2 | 3 | import cn.nukkit.event.player.PlayerFormRespondedEvent; 4 | import cn.nukkit.form.window.FormWindowModal; 5 | import ua.leonidius.trdinterface.Message; 6 | import ua.leonidius.trdinterface.controllers.ModalController; 7 | 8 | public class ModalScreen extends FormWindowModal implements Screen { 9 | 10 | private transient boolean ignoresStack = true; 11 | private transient final ModalController controller; 12 | 13 | public ModalScreen(String title, String content, ModalController controller) { 14 | super(title, content, Message.BTN_YES.getText(), Message.BTN_NO.getText()); 15 | this.controller = controller; 16 | } 17 | 18 | @Override 19 | public void setIgnoreStack(boolean ignoresStack) { 20 | this.ignoresStack = ignoresStack; 21 | } 22 | 23 | @Override 24 | public boolean ignoresStack() { 25 | return ignoresStack; 26 | } 27 | 28 | @Override 29 | public void onResponse(PlayerFormRespondedEvent event) { 30 | if (getResponse().getClickedButtonId() == 0) { // Positive button clicked 31 | controller.onPositiveResponse(); 32 | } else controller.onNegativeResponse(); 33 | } 34 | 35 | @Override 36 | public void update() {} 37 | 38 | } -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/screens/NamingScreen.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.screens; 2 | 3 | import cn.nukkit.event.player.PlayerFormRespondedEvent; 4 | import cn.nukkit.form.element.ElementInput; 5 | import ua.leonidius.trdinterface.controllers.NamingController; 6 | 7 | /** 8 | * This is a generic screen for naming things 9 | * (i.e. naming a new category, renaming an existing one etc.) 10 | */ 11 | public class NamingScreen extends CustomScreen { 12 | 13 | private transient final NamingController controller; 14 | 15 | public NamingScreen(NamingController controller, String title, 16 | String label, String text) { 17 | super(title); 18 | this.controller = controller; 19 | addElement(new ElementInput(label, "", text)); 20 | } 21 | 22 | @Override 23 | public void onResponse(PlayerFormRespondedEvent event) { 24 | String name = getResponse().getInputResponse(0); 25 | if (name.isEmpty()) controller.back(); 26 | else controller.submitName(name); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/screens/Screen.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.screens; 2 | 3 | import cn.nukkit.event.player.PlayerFormRespondedEvent; 4 | 5 | /** 6 | * Created by Leonidius20 on 04.07.18. 7 | */ 8 | public interface Screen { 9 | 10 | void onResponse(PlayerFormRespondedEvent event); 11 | 12 | // void onClose(PlayerFormRespondedEvent event); 13 | 14 | void setIgnoreStack(boolean ignoresStack); 15 | 16 | boolean ignoresStack(); 17 | 18 | /** 19 | * Called before showing the screen for the first time 20 | * and when returning to the screen using a back button 21 | */ 22 | void update(); 23 | 24 | } -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/screens/SimpleScreen.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.screens; 2 | 3 | import cn.nukkit.event.player.PlayerFormRespondedEvent; 4 | import cn.nukkit.form.element.ElementButton; 5 | import cn.nukkit.form.window.FormWindowSimple; 6 | import ua.leonidius.trdinterface.views.elements.CallbackButton; 7 | 8 | public abstract class SimpleScreen extends FormWindowSimple implements Screen { 9 | 10 | private transient boolean ignoresStack = false; 11 | 12 | public SimpleScreen() { 13 | super("", ""); 14 | } 15 | 16 | public SimpleScreen(String title) { 17 | super(title, ""); 18 | } 19 | 20 | public SimpleScreen(String title, String content) { 21 | super(title, content); 22 | } 23 | 24 | /*@Override 25 | public void onClose(PlayerFormRespondedEvent event) { 26 | manager.onClose(); 27 | manager = null; 28 | }*/ 29 | 30 | @Override 31 | public void setIgnoreStack(boolean ignoresStack) { 32 | this.ignoresStack = ignoresStack; 33 | } 34 | 35 | @Override 36 | public boolean ignoresStack() { 37 | return ignoresStack; 38 | } 39 | 40 | @Override 41 | public void onResponse(PlayerFormRespondedEvent event) { 42 | ElementButton button = getResponse().getClickedButton(); 43 | if (button instanceof CallbackButton) { 44 | ((CallbackButton) button).executeCallback(); 45 | } 46 | } 47 | 48 | @Override 49 | public void update() { 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/screens/buy/items/edit/AddDiscountScreen.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.screens.buy.items.edit; 2 | 3 | import cn.nukkit.event.player.PlayerFormRespondedEvent; 4 | import cn.nukkit.form.element.ElementDropdown; 5 | import cn.nukkit.form.element.ElementInput; 6 | import ua.leonidius.trdinterface.Message; 7 | import ua.leonidius.trdinterface.controllers.buy.items.discounts.AddDiscountController; 8 | import ua.leonidius.trdinterface.utils.TimeUnit; 9 | import ua.leonidius.trdinterface.views.screens.CustomScreen; 10 | 11 | import java.util.LinkedList; 12 | 13 | /** 14 | * Represents the screen for adding discounts to buyable items. 15 | * 16 | * @author Leonidius20 17 | */ 18 | public class AddDiscountScreen extends CustomScreen { 19 | 20 | private final transient AddDiscountController controller; 21 | 22 | public AddDiscountScreen(AddDiscountController controller) { 23 | super(Message.WDW_EDIT_DISCOUNT_TITLE.getText()); 24 | 25 | this.controller = controller; 26 | 27 | LinkedList durationUnits = new LinkedList<>(); 28 | for (TimeUnit unit : controller.getTimeUnits()) { 29 | durationUnits.add(unit.getName()); 30 | } 31 | 32 | // Discount percentage, index 0 33 | addElement(new ElementInput(Message.WDW_EDIT_DISCOUNT_HINT.getText())); 34 | 35 | // Discount duration, index 1 36 | addElement(new ElementInput(Message.WDW_EDIT_DISCOUNT_DURATION.getText())); 37 | 38 | // Discount duration unit of measure, index 2 39 | addElement(new ElementDropdown("", durationUnits)); 40 | } 41 | 42 | @Override 43 | public void onResponse(PlayerFormRespondedEvent event) { 44 | String percentS = getResponse().getInputResponse(0); 45 | String durationS = getResponse().getInputResponse(1); 46 | int unitIndex = getResponse().getDropdownResponse(2).getElementID(); 47 | TimeUnit unit = TimeUnit.values()[unitIndex]; 48 | controller.addDiscount(percentS, durationS, unit); 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/screens/buy/items/edit/ManageBuyableItemScreen.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.screens.buy.items.edit; 2 | 3 | import ua.leonidius.trdinterface.Message; 4 | import ua.leonidius.trdinterface.controllers.buy.items.edit.ManageBuyableItemController; 5 | import ua.leonidius.trdinterface.views.elements.CallbackButton; 6 | import ua.leonidius.trdinterface.views.screens.SimpleScreen; 7 | 8 | /** 9 | * This screen is shown to players who have permissions to manage the shop. 10 | * It allows to select an action to perform on an item: 11 | * buy, edit, delete, add or remove discount, manage enchantments 12 | */ 13 | public class ManageBuyableItemScreen extends SimpleScreen { 14 | 15 | private final transient ManageBuyableItemController controller; 16 | 17 | /** 18 | * Used to save the reference to the add/remove discount button, 19 | * so that the button's name and action can be changed in update() 20 | * in case a discount was added/removed 21 | */ 22 | private final transient CallbackButton discountButton; 23 | 24 | public ManageBuyableItemScreen(ManageBuyableItemController controller) { 25 | super(Message.WDW_EDIT_ITEM_TITLE.getText()); 26 | 27 | this.controller = controller; 28 | 29 | addButton(new CallbackButton(Message.BTN_BACK.getText(), controller::back)); 30 | addButton(new CallbackButton(Message.BTN_BUY_ITEM.getText(), 31 | controller::buyItem)); 32 | addButton(new CallbackButton(Message.BTN_EDIT_ITEM.getText(), 33 | controller::editItem)); 34 | addButton(new CallbackButton(Message.BTN_MANAGE_ENCHANTMENTS.getText(), 35 | controller::manageEnchantments)); 36 | addButton(new CallbackButton(Message.BTN_DELETE_ITEM.getText(), 37 | controller::deleteItem)); 38 | 39 | discountButton = new CallbackButton("", null); 40 | addButton(discountButton); 41 | } 42 | 43 | @Override 44 | public void update() { 45 | setContent(controller.buildItemDescription()); 46 | if (controller.hasDiscount()) { 47 | discountButton.setText(Message.BTN_REMOVE_DISCOUNT.getText()); 48 | discountButton.setCallback(controller::removeDiscount); 49 | } else { 50 | discountButton.setText(Message.BTN_ADD_DISCOUNT.getText()); 51 | discountButton.setCallback(controller::addDiscount); 52 | } 53 | } 54 | 55 | } -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/screens/buy/items/edit/enchantment/AddEnchantmentScreen.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.screens.buy.items.edit.enchantment; 2 | 3 | import cn.nukkit.event.player.PlayerFormRespondedEvent; 4 | import cn.nukkit.form.element.ElementDropdown; 5 | import cn.nukkit.form.element.ElementSlider; 6 | import cn.nukkit.item.enchantment.Enchantment; 7 | import ua.leonidius.trdinterface.Message; 8 | import ua.leonidius.trdinterface.controllers.AddEnchantmentController; 9 | import ua.leonidius.trdinterface.views.screens.CustomScreen; 10 | 11 | public class AddEnchantmentScreen extends CustomScreen { 12 | 13 | private transient final AddEnchantmentController controller; 14 | 15 | public AddEnchantmentScreen(AddEnchantmentController controller) { 16 | super(Message.WDW_ADD_ENCHANTMENT_TITLE.getText()); 17 | 18 | this.controller = controller; 19 | 20 | ElementDropdown dropdown = new ElementDropdown(Message.WDW_ADD_ENCHANTMENT_SELECTOR_HINT.getText()); 21 | 22 | for (Enchantment enchantment : Enchantment.getEnchantments()) { 23 | dropdown.addOption(enchantment.getName()); 24 | } 25 | 26 | addElement(dropdown); // 0 27 | 28 | addElement(new ElementSlider(Message.WDW_ADD_ENCHANTMENT_LEVEL_HINT.getText(), 29 | 0, 5, 1, 0)); // 1 30 | } 31 | 32 | @Override 33 | public void onResponse(PlayerFormRespondedEvent event) { 34 | int enchantmentLevel = (int) getResponse().getSliderResponse(1); 35 | 36 | if (enchantmentLevel == 0) { // Going back 37 | controller.back(); 38 | return; 39 | } 40 | 41 | int enchantmentId = getResponse().getDropdownResponse(0).getElementID(); 42 | 43 | controller.selectEnchantment(enchantmentId, enchantmentLevel); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/screens/sell/edit/ManageSellableItemScreen.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.screens.sell.edit; 2 | 3 | import ua.leonidius.trdinterface.Message; 4 | import ua.leonidius.trdinterface.controllers.sell.edit.ManageSellableItemController; 5 | import ua.leonidius.trdinterface.views.elements.CallbackButton; 6 | import ua.leonidius.trdinterface.views.screens.SimpleScreen; 7 | 8 | public class ManageSellableItemScreen extends SimpleScreen { 9 | 10 | private final transient ManageSellableItemController controller; 11 | 12 | public ManageSellableItemScreen(ManageSellableItemController controller) { 13 | super(controller.showEditingButtons() 14 | ? Message.WDW_EDIT_ITEM_TITLE.getText() 15 | : Message.WDW_VIEWING_SELLABLE_ITEM.getText()); 16 | this.controller = controller; 17 | 18 | addButton(new CallbackButton(Message.BTN_BACK.getText(), controller::back)); 19 | 20 | if (controller.showEditingButtons()) { 21 | addButton(new CallbackButton(Message.BTN_EDIT_ITEM.getText(), 22 | controller::editItem)); 23 | addButton(new CallbackButton(Message.BTN_MANAGE_ENCHANTMENTS.getText(), 24 | controller::manageEnchantments)); 25 | addButton(new CallbackButton(Message.BTN_DELETE_ITEM.getText(), 26 | controller::deleteItem)); 27 | } 28 | } 29 | 30 | @Override 31 | public void update() { 32 | setContent(controller.buildItemDescription()); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/screens/translations/AddTranslationScreen.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.screens.translations; 2 | 3 | import cn.nukkit.event.player.PlayerFormRespondedEvent; 4 | import cn.nukkit.form.element.ElementInput; 5 | import ua.leonidius.trdinterface.Message; 6 | import ua.leonidius.trdinterface.controllers.translations.AddTranslationController; 7 | import ua.leonidius.trdinterface.views.screens.CustomScreen; 8 | 9 | /** 10 | * Created by Leonidius20 on 11.08.18. 11 | */ 12 | public class AddTranslationScreen extends CustomScreen { 13 | 14 | private transient final AddTranslationController controller; 15 | 16 | public AddTranslationScreen(AddTranslationController controller) { 17 | super(Message.WDW_ADD_CUSTOM_NAME_TITLE.getText()); 18 | this.controller = controller; 19 | addElement(new ElementInput(Message.WDW_ADD_ITEM_ID.getText())); // 0 20 | addElement(new ElementInput(Message.WDW_CUSTOM_NAME_HINT.getText())); // 1 21 | } 22 | 23 | public void onResponse(PlayerFormRespondedEvent event) { 24 | String itemId = getResponse().getInputResponse(0); 25 | String translation = getResponse().getInputResponse(1); 26 | controller.submitInput(itemId, translation); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/ua/leonidius/trdinterface/views/screens/translations/CustomNameMenuScreen.java: -------------------------------------------------------------------------------- 1 | package ua.leonidius.trdinterface.views.screens.translations; 2 | 3 | import ua.leonidius.trdinterface.Message; 4 | import ua.leonidius.trdinterface.controllers.translations.TranslationMenuController; 5 | import ua.leonidius.trdinterface.views.elements.CallbackButton; 6 | import ua.leonidius.trdinterface.views.screens.SimpleScreen; 7 | 8 | /** 9 | * Created by Leonidius20 on 11.08.18. 10 | */ 11 | public class CustomNameMenuScreen extends SimpleScreen { 12 | 13 | private final transient TranslationMenuController controller; 14 | 15 | public CustomNameMenuScreen(TranslationMenuController controller) { 16 | super(Message.WDW_CUSTOM_NAME_TITLE.getText(), ""); 17 | 18 | this.controller = controller; 19 | 20 | addButton(new CallbackButton(Message.BTN_BACK.getText(), controller::back)); 21 | addButton(new CallbackButton(Message.BTN_EDIT_CUSTOM_NAME.getText(), 22 | controller::editTranslation)); 23 | addButton(new CallbackButton(Message.BTN_DELETE_CUSTOM_NAME.getText(), 24 | controller::deleteTranslation)); 25 | } 26 | 27 | @Override 28 | public void update() { 29 | setContent(controller.getContent()); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/resources/config.yml: -------------------------------------------------------------------------------- 1 | # Plugin language. if - server language will be used. 2 | # If there is no translation in your language, there will be created 3 | # a file called .lng with all strings in English. 4 | # You'll have to translate them. Once you've created a translation to 5 | # your language, you can start a pull request on github.com/Leonidius20/TradingInterface 6 | # placing .lng into src/main/resources/lang, and your translation will 7 | # officially become a part of the plugin. 8 | language: default 9 | # If true, a file with all strings will be created. You can edit the strings. 10 | save-translation: false 11 | # If true, all modifications of buyable and sellable items' lists will be logged. 12 | edit-logging: true 13 | # If true, all transactions will be logged. 14 | transaction-logging: false 15 | # If true, debug information will be shown in the console. 16 | debug: false -------------------------------------------------------------------------------- /src/main/resources/lang/chs.lng: -------------------------------------------------------------------------------- 1 | lng_save_fail: 保存语言文件失败 (.lng) 2 | lng_print_fail: '无法向玩家发送消息 ''null'': "%1%"' 3 | cmd_console: 无法从控制台执行此命令. 4 | cmd_shop: 打开商店界面 5 | wdw_main_title: 主菜单 6 | menu_buy: 购买物品 7 | menu_sell: 回收物品 8 | menu_edit_buy_list: 编辑购买物品 9 | menu_edit_sell_list: 编辑回收物品 10 | menu_browse_sell_list: Browse sellable items 11 | menu_custom_names: Custom item translations 12 | btn_back: < 返回 13 | btn_yes: 确定 14 | btn_no: 取消 15 | btn_edit_custom_name: '* Edit translation' 16 | btn_delete_custom_name: '* Delete translation' 17 | btn_add_custom_name: + Add translation 18 | wdw_success_title: 成功 19 | wdw_fail_title: 错误 20 | wdw_buy_cat_title: 选择一个类别 21 | wdw_buy_no_categories: 商店里没有商品类别.要使用商店.您必须至少拥有一个类别. 22 | wdw_buy_empty_cat: 此类别中没有产品. 23 | wdw_buy_title: 购买 %1% 24 | wdw_buy_name: 'Name: %1%' 25 | wdw_buy_original_name: 'Original name: %1% (%2%)' 26 | wdw_buy_price: '价格: %1%%2%' 27 | wdw_buy_discount: 'Discount: %1% percent, time left: %2%' 28 | wdw_buy_original_price: 'Price without discount: %1%%2%' 29 | wdw_buy_custom_lore: 'Lore: %1%' 30 | wdw_buy_enchantments: 'Enchantments: %1%' 31 | wdw_buy_amount: 选择数量 32 | wdw_select_zero_to_return: Select zero to return to the previous screen. 33 | wdw_sell_select_item: 选择待售商品 34 | wdw_sell_nothing: 你没有可出售的物品. 35 | wdw_browse_sellable_items_title: Browsing sellable items 36 | wdw_viewing_buyable_item: Viewing a buyable item 37 | wdw_viewing_sellable_item: Viewing a sellable item 38 | btn_item_sell: '%1% (%2%%3%) (%4% 个)' 39 | wdw_sell_title: 卖出 %1% 40 | wdw_edit_sellable_items_empty: There are no sellable items in the shop. 41 | btn_add_category: + 添加类别 42 | wdw_new_category: 创建新类别 43 | wdw_new_category_name: "名字 (leave blank to return):" 44 | wdw_new_category_fail: A category with such a name already exists. 45 | wdw_new_category_success: 已成功创建新类别. 46 | wdw_rename_category_title: 重命名类别 47 | wdw_rename_category_name: "新名称:" 48 | btn_rename_category: '* 重命名类别' 49 | btn_delete_category: '* 删除类别' 50 | btn_add_item: + 添加项目 51 | wdw_delete_category_title: 删除类别 52 | wdw_delete_category_conf: 您确定要删除类别 &l%1%&r? All of the items in this category will be deleted as well. 此操作无法撤消. 53 | wdw_add_item_title: 添加项目 54 | wdw_add_item_id: 项目ID 55 | wdw_add_item_price: 每件商品的价格 56 | wdw_add_item_custom_name: Custom name (optional) 57 | wdw_add_item_custom_lore: Custom lore (optional) 58 | wdw_add_item_enchantments: You will be able to edit enchantments later. 59 | wdw_add_buy_item_success: 您已成功将 &l%1%&r 添加到购买的商品列表中 60 | wdw_add_sell_item_success: 您已成功将 &l%1%&r 添加到回收的商品列表中. 61 | wdw_invalid_params: 参数不正确. 62 | wdw_add_item_missing_id: please fill in item's ID. 63 | wdw_add_item_invalid_id: the item with such an ID is not registered on the server. 64 | wdw_add_item_invalid_price: price format is invalid. 65 | wdw_edit_item_negative_price: price cannot be negative. 66 | wdw_add_item_invalid_nbt: failed to write NBT tag. 67 | wdw_edit_item_title: 编辑项目 68 | btn_edit_item: '* 编辑项目' 69 | btn_delete_item: '* 删除项目' 70 | btn_add_discount: + 添加折扣 71 | btn_remove_discount: '* Remove discount' 72 | btn_buy_item: Buy this item 73 | btn_manage_enchantments: Manage enchantments 74 | btn_add_enchantment: + Add enchantment 75 | wdw_delete_item_title: 删除项目 76 | wdw_delete_buy_item_conf: 您确定要从可供购买的商品列表中删除 &l%1%&r 吗?此操作无法撤消. 77 | wdw_delete_sell_item_conf: 您确定要从可供出售的商品列表中删除 &l%1%&r 吗?此操作无法撤消. 78 | wdw_edit_discount_title: Adding discount 79 | wdw_edit_discount_hint: 'Enter discount in percents (0 to return):' 80 | wdw_edit_discount_duration: 'Enter discount duration (numerical value):' 81 | wdw_edit_discount_more_than_100: Discount can't be bigger than 100% or less than 0%. 82 | wdw_remove_discount_conf: Are you sure you want to remove a %1% percent discount from &l%2%&r? 83 | wdw_custom_names_hint: You can add a custom translation for an item's name. Note! It has nothing to do with custom names (which can be added with an anvil) and only affects the item's name in the shop. 84 | wdw_custom_name_title: Item name translation 85 | wdw_custom_name_info: |- 86 | 商品编号: %1% 87 | 原名称: %2% 88 | Translation: %3% 89 | wdw_add_custom_name_title: Adding translation 90 | wdw_add_custom_name_fail: There is already a custom translation for this item's name. 91 | wdw_edit_custom_name_title: Editing translation 92 | wdw_custom_name_hint: 'Item''s name translation:' 93 | wdw_delete_custom_name_title: Deleting translation 94 | wdw_delete_custom_name_conf: Are you sure you want to delete a custom translation for the item's name? 此操作无法撤消. 95 | wdw_add_enchantment_title: Adding an enchantment 96 | wdw_add_enchantment_selector_hint: 'Select an enchantment:' 97 | wdw_add_enchantment_level_hint: Select a level (0 to return) 98 | wdw_manage_enchantments_title: Managing enchantments on %1% 99 | wdw_manage_enchantments_text: Select an enchantment from the list to remove it or press "+ Add enchantment" to add one. 100 | wdw_manage_enchantments_empty: There are no enchantments on this item 101 | wdw_remove_enchantment_title: Removing an enchantment 102 | wdw_remove_enchantment_conf: Are you sure you want to remove &l%1%&r from &l%2%&r? 103 | buy_no_money: 没有足够的钱来购买此商品. 104 | buy_no_space: 没有足够的背包空间来购买此商品. 105 | buy_no_space_and_money: 没有足够的钱和足够的背包空间来购买此项目. 106 | error: An error occurred. 107 | error_desc: 'An error occurred: %1%' 108 | buy_success: 您已成功购买 %1% 个 &l%2%&r 花费 %3%%4%. 109 | sell_success: 您已成功售出 %1% 个 &l%2%&r 获得 %3%%4%. 110 | log_category_added: '用户. %1% 添加了可供购买的新类别项目: %2%.' 111 | log_category_deleted: '用户. %1% 删除了可购买的商品类别: %2%.' 112 | log_category_renamed: '用户. %1% 已将可供购买的商品类别重命名为: %2% %4%.' 113 | log_buy_item_added: '用户. %1% 将 %2% (ID: %3%) 添加到可供购买的商品列表中, 价格: %4%%5%.' 114 | log_buy_item_added_with_custom_name: '用户. %1% 将 %2% (original name: %3%, ID: %4%) 添加到可供购买的商品列表中, 价格: %5%%6%.' 115 | log_buy_item_deleted: '用户. %1% 已从可供购买的商品列表中删除 %2% (ID: %3%)' 116 | log_buy_item_edited: 'User %1% has modified the buyable item %2%: %3%.' 117 | log_edited_id: changed ID from %1% to %2% 118 | log_edited_name: changed name from %1% to %2% 119 | log_edited_price: changed price from %1%%2% to %3%%2% 120 | log_edited_lore: changed lore from %1% to %2% 121 | log_added_lore: added a lore (%1%) 122 | log_removed_lore: removed lore (%1%) 123 | log_added_custom_name: added a custom name (%1%) 124 | log_edited_custom_name: changed custom name from %1% to %2% 125 | log_removed_custom_name: removed custom name (%1%) 126 | log_discount_added: 'User %1% has added a %2%% discount for %3% (ID: %4%) for %5%%6%.' 127 | log_discount_deleted: '用户. %1% 已删除 %2% (ID: %3%) 的折扣.' 128 | log_sell_item_added: '用户. %1% 将 %2% (ID: %3%) 添加到可供销售的商品列表中, 价格: %4%%5%.' 129 | log_sell_item_added_with_custom_name: '用户. %1% 将 %2% (original name: %3%, ID: %4%) 添加到可供销售的商品列表中, 价格: %5%%6%.' 130 | log_sell_item_deleted: '用户. %1% 已从可供出售的商品列表中删除 %2% (ID: %3%).' 131 | log_sell_item_edited: 'User %1% has modified the sellable item %2%: %3%.' 132 | log_buy_enchantment_added: User %1% has added %2% %3% enchantment to a buyable item %4% (%5%). 133 | log_sell_enchantment_added: User %1% has added %2% %3% enchantment to a sellable item %4% (%5%). 134 | log_buy_enchantment_removed: User %1% has removed %2% %3% enchantment from a buyable item %4% (%5%). 135 | log_sell_enchantment_removed: User %1% has removed %2% %3% enchantment from a sellable item %4% (%5%). 136 | log_bought: '玩家 %1% 购买 %2% 个 %3% (ID: %4%) 花费 %5%%6%.' 137 | log_sold: '玩家 %1% 回收 %2% 个 %3% (ID: %4%) 获得 %5%%6%.' 138 | log_translation_added: Player %1% have added a custom translation for %2% (%3%) - %4%. 139 | log_translation_changed: Player %1% have changed a custom translation for %2% (%3%) from %4% to %5%. 140 | log_translation_deleted: Player %1% have deleted a custom translation for %2% (%3%). 141 | log_buyable_items_found: Found buyList.yml, importing items to the database... 142 | log_sellable_items_found: Found sellList.yml, importing items to the database... 143 | log_translations_found: Found customItemNames.yml, importing translations to the database... 144 | log_buyable_items_imported: Imported %1% categories and %2% buyable items, buyList.yml deleted. 145 | log_sellable_items_imported: Imported %1% sellable items, sellList.yml deleted. 146 | log_all_translations_imported: Imported %1% translations, customItemNames.yml deleted. 147 | log_import_skipped_translations: Imported %1% translations, skipped %2% translations for items, for which there are already custom translations. Skipped items are kept in customItemNames.yml. 148 | log_import_failed: Failed to import. 149 | log_reading_nbt_failed: Error reading NBT tag on item with record_id %1% 150 | seconds: seconds 151 | minutes: minutes 152 | hours: hours 153 | days: days 154 | months: months 155 | infinity: infinity -------------------------------------------------------------------------------- /src/main/resources/lang/cht.lng: -------------------------------------------------------------------------------- 1 | lng_save_fail: '保存語言文件失敗 (.lng)' 2 | lng_print_fail: '無法向玩家發送消息 ''null'': "%1%"' 3 | cmd_console: 無法從控制台執行此命令. 4 | cmd_shop: 打開商店介面 5 | wdw_main_title: 主菜單 6 | menu_buy: 購買物品 7 | menu_sell: 回收物品 8 | menu_edit_buy_list: 編輯購買物品 9 | menu_edit_sell_list: 編輯回收物品 10 | menu_browse_sell_list: Browse sellable items 11 | menu_custom_names: Custom item translations 12 | btn_back: < 返回 13 | btn_yes: 確定 14 | btn_no: 取消 15 | btn_edit_custom_name: '* Edit translation' 16 | btn_delete_custom_name: '* Delete translation' 17 | btn_add_custom_name: + Add translation 18 | wdw_success_title: 成功 19 | wdw_fail_title: 錯誤 20 | wdw_buy_cat_title: 選擇一個類別 21 | wdw_buy_no_categories: 商店裡沒有商品類別.要使用商店.您必須至少擁有一個類別. 22 | wdw_buy_empty_cat: 此類別中沒有產品. 23 | wdw_buy_title: 購買 %1% 24 | wdw_buy_name: 'Name: %1%' 25 | wdw_buy_original_name: 'Original name: %1% (%2%)' 26 | wdw_buy_price: '價格: %1%%2%' 27 | wdw_buy_discount: 'Discount: %1% percent, time left: %2%' 28 | wdw_buy_original_price: 'Price without discount: %1%%2%' 29 | wdw_buy_custom_lore: 'Lore: %1%' 30 | wdw_buy_enchantments: 'Enchantments: %1%' 31 | wdw_buy_amount: 選擇數量 32 | wdw_select_zero_to_return: Select zero to return to the previous screen. 33 | wdw_sell_select_item: 選擇待售商品 34 | wdw_sell_nothing: 你沒有可出售的物品. 35 | wdw_browse_sellable_items_title: Browsing sellable items 36 | wdw_viewing_buyable_item: Viewing a buyable item 37 | wdw_viewing_sellable_item: Viewing a sellable item 38 | btn_item_sell: '%1% (%2%%3%) (%4% 個)' 39 | wdw_sell_title: 賣出 %1% 40 | wdw_edit_sellable_items_empty: There are no sellable items in the shop. 41 | btn_add_category: + 添加類別 42 | wdw_new_category: 創建新類別 43 | wdw_new_category_name: "名字 (leave blank to return):" 44 | wdw_new_category_fail: A category with such a name already exists. 45 | wdw_new_category_success: 已成功創建新類別. 46 | wdw_rename_category_title: 重命名類別 47 | wdw_rename_category_name: "新名稱:" 48 | btn_rename_category: '* 重命名類別' 49 | btn_delete_category: '* 刪除類別' 50 | btn_add_item: + 添加項目 51 | wdw_delete_category_title: 刪除類別 52 | wdw_delete_category_conf: 您確定要刪除類別 &l%1%&r? All of the items in this category will be deleted as well. 此操作無法撤消. 53 | wdw_add_item_title: 添加項目 54 | wdw_add_item_id: 項目ID 55 | wdw_add_item_price: 每件商品的價格 56 | wdw_add_item_custom_name: Custom name (optional) 57 | wdw_add_item_custom_lore: Custom lore (optional) 58 | wdw_add_item_enchantments: You will be able to edit enchantments later. 59 | wdw_add_buy_item_success: 您已成功將 &l%1%&r 添加到購買的商品列表中 60 | wdw_add_sell_item_success: 您已成功將 &l%1%&r 添加到回收的商品列表中. 61 | wdw_invalid_params: 參數不正確. 62 | wdw_add_item_missing_id: please fill in item's ID. 63 | wdw_add_item_invalid_id: the item with such an ID is not registered on the server. 64 | wdw_add_item_invalid_price: price format is invalid. 65 | wdw_edit_item_negative_price: price cannot be negative. 66 | wdw_add_item_invalid_nbt: failed to write NBT tag. 67 | wdw_edit_item_title: 編輯項目 68 | btn_edit_item: '* 編輯項目' 69 | btn_delete_item: '* 刪除項目' 70 | btn_add_discount: + 添加折扣 71 | btn_remove_discount: '* Remove discount' 72 | btn_buy_item: Buy this item 73 | btn_manage_enchantments: Manage enchantments 74 | btn_add_enchantment: + Add enchantment 75 | wdw_delete_item_title: 刪除項目 76 | wdw_delete_buy_item_conf: 您確定要從可供購買的商品列表中刪除 &l%1%&r 嗎?此操作無法撤消. 77 | wdw_delete_sell_item_conf: 您確定要從可供出售的商品列表中刪除 &l%1%&r 嗎?此操作無法撤消. 78 | wdw_edit_discount_title: Adding discount 79 | wdw_edit_discount_hint: 'Enter discount in percents (0 to return):' 80 | wdw_edit_discount_duration: 'Enter discount duration (numerical value):' 81 | wdw_edit_discount_more_than_100: Discount can't be bigger than 100% or less than 0%. 82 | wdw_remove_discount_conf: Are you sure you want to remove a %1% percent discount from &l%2%&r? 83 | wdw_custom_names_hint: You can add a custom translation for an item's name. Note! It has nothing to do with custom names (which can be added with an anvil) and only affects the item's name in the shop. 84 | wdw_custom_name_title: Item name translation 85 | wdw_custom_name_info: |- 86 | 商品編號: %1% 87 | 原名稱: %2% 88 | Translation: %3% 89 | wdw_add_custom_name_title: Adding translation 90 | wdw_add_custom_name_fail: There is already a custom translation for this item's name. 91 | wdw_edit_custom_name_title: Editing translation 92 | wdw_custom_name_hint: 'Item''s name translation:' 93 | wdw_delete_custom_name_title: Deleting translation 94 | wdw_delete_custom_name_conf: Are you sure you want to delete a custom translation for the item's name? 此操作無法撤消. 95 | wdw_add_enchantment_title: Adding an enchantment 96 | wdw_add_enchantment_selector_hint: 'Select an enchantment:' 97 | wdw_add_enchantment_level_hint: Select a level (0 to return) 98 | wdw_manage_enchantments_title: Managing enchantments on %1% 99 | wdw_manage_enchantments_text: Select an enchantment from the list to remove it or press "+ Add enchantment" to add one. 100 | wdw_manage_enchantments_empty: There are no enchantments on this item 101 | wdw_remove_enchantment_title: Removing an enchantment 102 | wdw_remove_enchantment_conf: Are you sure you want to remove &l%1%&r from &l%2%&r? 103 | buy_no_money: 沒有足夠的錢來購買此商品. 104 | buy_no_space: 沒有足夠的背包空間來購買此商品. 105 | buy_no_space_and_money: 沒有足夠的錢和足夠的背包空間來購買此項目. 106 | error: An error occurred. 107 | error_desc: 'An error occurred: %1%' 108 | buy_success: 您已成功購買 %1% 個 &l%2%&r 花費 %3%%4%. 109 | sell_success: 您已成功售出 %1% 個 &l%2%&r 獲得 %3%%4%. 110 | log_category_added: '用戶. %1% 添加了可供購買的新類別項目: %2%.' 111 | log_category_deleted: '用戶. %1% 刪除了可購買的商品類別: %2%.' 112 | log_category_renamed: '用戶. %1% 已將可供購買的商品類別重命名為: %2% %3%.' 113 | log_buy_item_added: '用戶. %1% 將 %2% (ID: %3%) 添加到可供購買的商品列表中, 價格: %4%%5%.' 114 | log_buy_item_added_with_custom_name: '用戶. %1% 將 %2% (original name: %3%, ID: %4%) 添加到可供購買的商品列表中, 價格: %5%%6%.' 115 | log_buy_item_deleted: '用戶. %1% 已從可供購買的商品列表中刪除 %2% (ID: %3%)' 116 | log_buy_item_edited: 'User %1% has modified the buyable item %2%: %3%.' 117 | log_edited_id: changed ID from %1% to %2% 118 | log_edited_name: changed name from %1% to %2% 119 | log_edited_price: changed price from %1%%2% to %3%%2% 120 | log_edited_lore: changed lore from %1% to %2% 121 | log_added_lore: added a lore (%1%) 122 | log_removed_lore: removed lore (%1%) 123 | log_added_custom_name: added a custom name (%1%) 124 | log_edited_custom_name: changed custom name from %1% to %2% 125 | log_removed_custom_name: removed custom name (%1%) 126 | log_discount_added: 'User %1% has added a %2%% discount for %3% (ID: %4%) for %5%%6%.' 127 | log_discount_edited: '用戶. %1% 更改折扣: %2% (ID: %3%), 新折扣: %4%%, 舊折扣: %5%%.' 128 | log_discount_deleted: '用戶. %1% 已刪除 %2% (ID: %3%) 的折扣.' 129 | log_sell_item_added: '用戶. %1% 將 %2% (ID: %3%) 添加到可供銷售的商品列表中, 價格: %4%%5%.' 130 | log_sell_item_added_with_custom_name: 'User %1% has added %2% (original name: %3%, ID: %4%) to the list of sellable items, price: %5%%6%.' 131 | log_sell_item_deleted: '用戶. %1% 已從可供出售的商品列表中刪除 %2% (ID: %3%).' 132 | log_sell_item_edited: 'User %1% has modified the sellable item %2%: %3%.' 133 | log_buy_enchantment_added: User %1% has added %2% %3% enchantment to a buyable item %4% (%5%). 134 | log_sell_enchantment_added: User %1% has added %2% %3% enchantment to a sellable item %4% (%5%). 135 | log_buy_enchantment_removed: User %1% has removed %2% %3% enchantment from a buyable item %4% (%5%). 136 | log_sell_enchantment_removed: User %1% has removed %2% %3% enchantment from a sellable item %4% (%5%). 137 | log_bought: '玩家 %1% 購買 %2% 個 %3% (ID: %4%) 花費 %5%%6%.' 138 | log_sold: '玩家 %1% 回收 %2% 個 %3% (ID: %4%) 獲得 %5%%6%.' 139 | log_translation_added: Player %1% have added a custom translation for %2% (%3%) - %4%. 140 | log_translation_changed: Player %1% have changed a custom translation for %2% (%3%) from %4% to %5%. 141 | log_translation_deleted: Player %1% have deleted a custom translation for %2% (%3%). 142 | log_buyable_items_found: Found buyList.yml, importing items to the database... 143 | log_sellable_items_found: Found sellList.yml, importing items to the database... 144 | log_translations_found: Found customItemNames.yml, importing translations to the database... 145 | log_buyable_items_imported: Imported %1% categories and %2% buyable items, buyList.yml deleted. 146 | log_sellable_items_imported: Imported %1% sellable items, sellList.yml deleted. 147 | log_all_translations_imported: Imported %1% translations, customItemNames.yml deleted. 148 | log_import_skipped_translations: Imported %1% translations, skipped %2% translations for items, for which there are already custom translations. Skipped items are kept in customItemNames.yml. 149 | log_import_failed: Failed to import. 150 | log_reading_nbt_failed: Error reading NBT tag on item with record_id %1% 151 | seconds: seconds 152 | minutes: minutes 153 | hours: hours 154 | days: days 155 | months: months 156 | infinity: infinity -------------------------------------------------------------------------------- /src/main/resources/lang/rus.lng: -------------------------------------------------------------------------------- 1 | lng_save_fail: Не удалось сохранить языковой файл (.lng) 2 | lng_print_fail: 'Не удалось отправить сообщение игроку ''null'': "%1%"' 3 | cmd_console: Эту команду нельзя выполнить из консоли. 4 | cmd_shop: Открыть интерфейс магазина 5 | wdw_main_title: Главное меню 6 | menu_buy: Покупка предметов 7 | menu_sell: Продажа предметов 8 | menu_edit_buy_list: Ред. покупаемые предметы 9 | menu_edit_sell_list: Ред. продаваемые предметы 10 | menu_browse_sell_list: Список продаваемых предметов 11 | menu_custom_names: Переводы названий предметов 12 | btn_back: < Назад 13 | btn_yes: Да 14 | btn_no: Нет 15 | btn_edit_custom_name: '* Ред. перевод' 16 | btn_delete_custom_name: '* Удалить перевод' 17 | btn_add_custom_name: + Добавить перевод 18 | wdw_success_title: Успех 19 | wdw_fail_title: Неудача 20 | wdw_buy_cat_title: Выберите категорию 21 | wdw_buy_no_categories: В магазине отсутствуют категории товаров. Для использования магазина необходимо наличие как минимум одной категории. 22 | wdw_buy_empty_cat: В этой категории нет товаров. 23 | wdw_buy_title: Приобретение %1% 24 | wdw_buy_name: 'Название: %1%' 25 | wdw_buy_original_name: 'Оригинальное название: %1% (%2%)' 26 | wdw_buy_price: 'Цена: %1%%2% за штуку' 27 | wdw_buy_discount: 'Скидка: %1% процентов, осталось времени: %2%' 28 | wdw_buy_original_price: 'Цена без скидки: %1%%2%' 29 | wdw_buy_custom_lore: 'Описание: %1%' 30 | wdw_buy_enchantments: 'Зачарования: %1%' 31 | wdw_buy_amount: Выберите количество 32 | wdw_select_zero_to_return: Выберите ноль, чтоб вернуться на предыдущий экран. 33 | wdw_sell_select_item: Выберите предмет для продажи 34 | wdw_sell_nothing: У вас нет предметов, которые можно продавать. 35 | wdw_browse_sellable_items_title: Просмотр продаваемых предметов 36 | wdw_viewing_buyable_item: Просмотр покупаемого предмета 37 | wdw_viewing_sellable_item: Просмотр продаваемого предмета 38 | btn_item_sell: '%1% (%2%%3%) (%4% шт.)' 39 | wdw_sell_title: Продажа %1% 40 | wdw_edit_sellable_items_empty: В магазине нет предметов, доступных для продажи. 41 | btn_add_category: + Добавить категорию 42 | wdw_new_category: Создание новой категории 43 | wdw_new_category_name: 'Выберите имя (оставьте пустым, чтоб вернуться):' 44 | wdw_new_category_fail: Категория с таким названием уже существует. 45 | wdw_new_category_success: Новая категория успешно создана. 46 | wdw_rename_category_title: Переименование категории 47 | wdw_rename_category_name: 'Выберите новое имя:' 48 | btn_rename_category: '* Переименовать категорию' 49 | btn_delete_category: '* Удалить категорию' 50 | btn_add_item: + Добавить предмет 51 | wdw_delete_category_title: Удаление категории 52 | wdw_delete_category_conf: Вы уверены, что хотите удалить категорию &l%1%&r? Все предметы из этой категории будут также удалены. Это действие нельзя отменить. 53 | wdw_add_item_title: Добавление предмета 54 | wdw_add_item_id: ID предмета (числовой или строчный) 55 | wdw_add_item_price: Цена за штуку 56 | wdw_add_item_custom_name: Пользовательское название (опционально) 57 | wdw_add_item_custom_lore: Пользовательское описание (опционально) 58 | wdw_add_item_enchantments: Вы сможете отредактировать зачарования позже. 59 | wdw_add_buy_item_success: Вы успешно добавили &l%1%&r в список предметов, доступных для покупки. 60 | wdw_add_sell_item_success: Вы успешно добавили &l%1%&r в список предметов, доступных для продажи. 61 | wdw_invalid_params: Некорректные параметры. 62 | wdw_add_item_missing_id: пожалуйста, введите ID предмета. 63 | wdw_add_item_invalid_id: предмет с таким ID не зарегестрирован на сервере. 64 | wdw_add_item_invalid_price: некорректный формат цены. 65 | wdw_edit_item_negative_price: цена не может быть отрицательной. 66 | wdw_add_item_invalid_nbt: не удалось записать NBT тег. 67 | wdw_edit_item_title: Редактирование предмета 68 | btn_edit_item: '* Ред. предмет' 69 | btn_delete_item: '* Удалить предмет' 70 | btn_add_discount: + Добавить скидку 71 | btn_remove_discount: '* Убрать скидку' 72 | btn_buy_item: Купить этот предмет 73 | btn_manage_enchantments: Управление зачарованиями 74 | btn_add_enchantment: + Добавить зачарование 75 | wdw_delete_item_title: Удаление предмета 76 | wdw_delete_buy_item_conf: Вы уверены, что хотите удалить &l%1%&r из списка предметов, доступных для покупки? Это действие нельзя отменить. 77 | wdw_delete_sell_item_conf: Вы уверены, что хотите удалить &l%1%&r из списка предметов, доступных для продажи? Это действие нельзя отменить. 78 | wdw_edit_discount_title: Добавление скидки 79 | wdw_edit_discount_hint: 'Введите скидку в процентах (0, чтобы вернуться):' 80 | wdw_edit_discount_duration: 'Введите продолжительность скидки (числовое значение):' 81 | wdw_edit_discount_more_than_100: Скидка не может быть больше чем 100% или меньше чем 0%. 82 | wdw_remove_discount_conf: Вы уверены, что хотите убрать скидку %1% процентов с &l%2%&r? 83 | wdw_custom_names_hint: Вы можете добавить перевод названия предмета. Обратите внимание! Это не относится к польз. названиям (которые можно добавлять с помощью наковальни) и влияет только на отображение названия предмета в магазине. 84 | wdw_custom_name_title: Перевод названия предмета 85 | wdw_custom_name_info: |- 86 | ID предмета: %1% 87 | Оригинальное название: %2% 88 | Перевод: %3% 89 | wdw_add_custom_name_title: Добавление перевода 90 | wdw_add_custom_name_fail: Для имени этого предмета уже есть перевод. 91 | wdw_edit_custom_name_title: Ред. перевода 92 | wdw_custom_name_hint: 'Перевод названия предмета:' 93 | wdw_delete_custom_name_title: Удаление перевода 94 | wdw_delete_custom_name_conf: Вы уверены, что хотите удалить перевод названия этого предмета? Это действие нельзя отменить. 95 | wdw_add_enchantment_title: Добавление зачарования 96 | wdw_add_enchantment_selector_hint: "Выберите зачарование:" 97 | wdw_add_enchantment_level_hint: Выберите уровень (0, чтобы вернуться) 98 | wdw_manage_enchantments_title: Управление зачарованиями на %1% 99 | wdw_manage_enchantments_text: Выберите зачарование из списка, чтоб убрать его, или нажмите "+ Добавить зачарование". 100 | wdw_manage_enchantments_empty: На этом предмете нет зачарований 101 | wdw_remove_enchantment_title: Удаление зачарования 102 | wdw_remove_enchantment_conf: Вы уверены, что хотите удалить зачарование &l%1%&r с &l%2%&r? 103 | buy_no_money: Недостаточно денег для покупки этого предмета. 104 | buy_no_space: Недостаточно места в инвентаре для покупки этого предмета. 105 | buy_no_space_and_money: Недостаточно денег и свободного места в инвентаре для покупки этого предмета. 106 | error: Произошла ошибка. 107 | error_desc: 'Произошла ошибка: %1%' 108 | buy_success: Вы успешно купили %1% шт. &l%2%&r за %3%%4%. 109 | sell_success: Вы успешно продали %1% шт. &l%2%&r за %3%%4%. 110 | log_category_added: 'Польз. %1% добавил новую категорию предметов, доступных для покупки, под названием %2%.' 111 | log_category_deleted: 'Польз. %1% удалил категорию предметов, доступных для покупки, под названием %2%.' 112 | log_category_renamed: 'Польз. %1% переименовал категорию предметов, доступных для покупки, под названием %2% в %3%.' 113 | log_buy_item_added: 'Польз. %1% добавил %2% (ID: %3%) в список предметов, доступных для покупки, 114 | цена: %4%%5%.' 115 | log_buy_item_added_with_custom_name: 'Польз. %1% добавил %2% (оригинальное название: %3%, ID: %4%) в список предметов, доступных для покупки, цена: %5%%6%.' 116 | log_buy_item_deleted: 'Польз. %1% удалил %2% (ID: %3%) из списка предметов, доступных для покупки.' 117 | log_buy_item_edited: 'Польз. %1% отредактировал предмет %2%, доступный для покупки: %3%.' 118 | log_edited_id: сменил ID с %1% на %2% 119 | log_edited_name: сменил название с %1% на %2% 120 | log_edited_price: сменил цену с %1%%2% на %3%%2% 121 | log_edited_lore: сменил описание с %1% на %2% 122 | log_added_lore: добавил описание (%1%) 123 | log_removed_lore: удалил описание (%1%) 124 | log_added_custom_name: добавил пользовательское название (%1%) 125 | log_edited_custom_name: сменил пользовательское название с %1% на %2% 126 | log_removed_custom_name: удалил пользовательское название (%1%) 127 | log_discount_added: 'Польз. %1% добавил скидку %2%% на %3% (ID: %4%) на %5%%6%.' 128 | log_discount_deleted: 'Польз. %1% удалил скидку на %2% (ID: %3%).' 129 | log_sell_item_added: 'Польз. %1% добавил %2% (ID: %3%) в список предметов, доступных для продажи, 130 | цена: %4%%5%.' 131 | log_sell_item_added_with_custom_name: 'Польз. %1% добавил %2% (оригинальное название: %3%, ID: %4%) в список предметов, доступных для продажи, цена: %5%%6%.' 132 | log_sell_item_deleted: 'Польз. %1% удалил %2% (ID: %3%) из списка предметов, доступных для продажи.' 133 | log_sell_item_edited: 'Польз. %1% отредактировал предмет %2%, доступный для продажи: %3%.' 134 | log_buy_enchantment_added: Польз. %1% добавил зачарование %2% %3% на предмет %4% (%5%), доступный для покупки. 135 | log_sell_enchantment_added: Польз. %1% добавил зачарование %2% %3% на предмет %4% (%5%), доступный для продажи. 136 | log_buy_enchantment_removed: Польз. %1% убрал зачарование %2% %3% с предмета %4% (%5%), доступного для покупки. 137 | log_sell_enchantment_removed: Польз. %1% убрал зачарование %2% %3% с предмета %4% (%5%), доступного для продажи. 138 | log_bought: 'Игрок %1% купил %2% шт. %3% (ID: %4%) за %5%%6%.' 139 | log_sold: 'Игрок %1% продал %2% шт. %3% (ID: %4%) за %5%%6%.' 140 | log_translation_added: Польз. %1% добавил перевод имени предмета %2% (%3%) - %4%. 141 | log_translation_changed: Польз. %1% сменил перевод имени предмета %2% (%3%) с %4% на %5%. 142 | log_translation_deleted: Польз. %1% удалил перевод имени предмета %2% (%3%). 143 | log_buyable_items_found: Найден файл buyList.yml, импортируем предметы в базу данных... 144 | log_sellable_items_found: Найден файл sellList.yml, импортируем предметы в базу данных... 145 | log_translations_found: Найден файл customItemNames.yml, импортируем переводы в базу данных... 146 | log_buyable_items_imported: Импортировано %1% категорий и %2% предметов, доступных для покупки, файл buyList.yml удалён. 147 | log_sellable_items_imported: Импортировано %1% предметов, доступных для продажи, файл sellList.yml удалён. 148 | log_all_translations_imported: Импортировано %1% переводов, файл customItemNames.yml удалён. 149 | log_import_skipped_translations: Импортировано %1% переводов, пропущено %2% переводов названий тех предметов, для которых уже есть переводы. Пропущенные переводы оставлены в файле customItemNames.yml. 150 | log_import_failed: Не удалось импортировать. 151 | log_reading_nbt_failed: Не удалось считать NBT тег предмета с record_id %1% 152 | seconds: секунд 153 | minutes: минут 154 | hours: часов 155 | days: дней 156 | months: месяцев 157 | infinity: бесконечность -------------------------------------------------------------------------------- /src/main/resources/lang/ukr.lng: -------------------------------------------------------------------------------- 1 | lng_save_fail: Не вдалося зберегти мовний файл (.lng) 2 | lng_print_fail: 'Не вдалося відправити повідомлення гравцю ''null'': "%1%"' 3 | cmd_console: Цю команду не можна виконати з консолі. 4 | cmd_shop: Відкрити інтерфейс магазина 5 | wdw_main_title: Головне меню 6 | menu_buy: Придбання предметів 7 | menu_sell: Продаж предметів 8 | menu_edit_buy_list: Ред. предмети, що покупаються 9 | menu_edit_sell_list: Ред. предмети, що продаються 10 | menu_browse_sell_list: Список предметів, що можна продавати 11 | menu_custom_names: Переклади назв предметів 12 | btn_back: < Назад 13 | btn_yes: Так 14 | btn_no: Ні 15 | btn_edit_custom_name: '* Ред. переклад' 16 | btn_delete_custom_name: '* Видалити переклад' 17 | btn_add_custom_name: '+ Додати переклад' 18 | wdw_success_title: Успіх 19 | wdw_fail_title: Невдача 20 | wdw_buy_cat_title: Оберіть категорію 21 | wdw_buy_no_categories: У магазині відсутні категорії товарів. Для використання магазина необхідно мати хоч одну категорію. 22 | wdw_buy_empty_cat: У цій категорії немає товарів. 23 | wdw_buy_title: Придбання %1% 24 | wdw_buy_name: 'Назва: %1%' 25 | wdw_buy_original_name: 'Оригінальна назва: %1% (%2%)' 26 | wdw_buy_price: 'Ціна: %1%%2% за штуку' 27 | wdw_buy_discount: 'Знижка: %1% відсотків, залишилось часу: %2%' 28 | wdw_buy_original_price: 'Ціна без знижки: %1%%2%' 29 | wdw_buy_custom_lore: 'Опис: %1%' 30 | wdw_buy_enchantments: 'Зачарування: %1%' 31 | wdw_buy_amount: Оберіть кількість 32 | wdw_select_zero_to_return: Оберіть нуль, щоб повернутись до попереднього екрану. 33 | wdw_sell_select_item: Виберіть предмет для продажу 34 | wdw_sell_nothing: У вас немає предметів, які можна було б продавати. 35 | wdw_browse_sellable_items_title: Перегляд предм., що можна продавати 36 | wdw_viewing_buyable_item: Перегляд предм., що можна придбати 37 | wdw_viewing_sellable_item: Перегляд предм., що можна продавати 38 | btn_item_sell: '%1% (%2%%3%) (%4% шт.)' 39 | wdw_sell_title: Продаж %1% 40 | wdw_edit_sellable_items_empty: В магазині немає предметів, що можна продавати. 41 | btn_add_category: + Додати категорію 42 | wdw_new_category: Створення нової категорії 43 | wdw_new_category_name: "Оберіть назву (залиште порожньою, щоб повернутися назад):" 44 | wdw_new_category_fail: Категорія с такою назвою вже існує. 45 | wdw_new_category_success: Нову категорію успішно створено. 46 | wdw_rename_category_title: Перейменування категорії 47 | wdw_rename_category_name: "Оберіть нову назву:" 48 | btn_rename_category: '* Перейменувати категорію' 49 | btn_delete_category: '* Видалити категорію' 50 | btn_add_item: + Додати предмет 51 | wdw_delete_category_title: Видалення категорії 52 | wdw_delete_category_conf: Ви впевнені, що хочете видалити категорію &l%1%&r? Всі предмети в цій категорії будуть також видалені. Цю дію неможливо скасувати. 53 | wdw_add_item_title: Додавання предмета 54 | wdw_add_item_title: Додавання предмета 55 | wdw_add_item_id: ID предмета (числовий или строковий) 56 | wdw_add_item_price: Ціна за штуку 57 | wdw_add_item_custom_name: 'Користувацька назва (необов’язково)' 58 | wdw_add_item_custom_lore: 'Користувацький опис (необов’язково)' 59 | wdw_add_item_enchantments: Ви зможете відредагувати зачарування пізніше. 60 | wdw_add_buy_item_success: Ви успішно додали &l%1%&r до списку предметів, доступних для придбання. 61 | wdw_add_sell_item_success: Ви успішно додали &l%1%&r до списку предметів, доступних для продажу. 62 | wdw_invalid_params: Некорректні параметри. 63 | wdw_add_item_missing_id: будь-ласка, вкажіть ID предмета. 64 | wdw_add_item_invalid_id: предмет з таким ID не зареєстровано на сервері. 65 | wdw_add_item_invalid_price: некоректний формат ціни. 66 | wdw_edit_item_negative_price: 'ціна не може бути від’ємною.' 67 | wdw_add_item_invalid_nbt: не вдалося записати NBT тег. 68 | wdw_edit_item_title: Редагування предмета 69 | btn_edit_item: '* Редагувати предмет' 70 | btn_delete_item: '* Видалити предмет' 71 | btn_add_discount: + Додати знижку 72 | btn_remove_discount: '* Прибрати знижку' 73 | btn_buy_item: Придбати цей предмет 74 | btn_manage_enchantments: Редагувати зачарування 75 | btn_add_enchantment: + Додати зачарування 76 | wdw_delete_item_title: Видалення предмета 77 | wdw_delete_buy_item_conf: Ви впевнені, що хочете видалити &l%1%&r зі списку предметів, доступних для придбання? Цю дію неможливо скасувати. 78 | wdw_delete_sell_item_conf: Ви впевнені, що хочете видалити &l%1%&r зі списку предметів, доступних для продажу? Цю дію неможливо скасувати. 79 | wdw_edit_discount_title: Додавання знижки 80 | wdw_edit_discount_hint: 'Введіть знижку у відсотках (введіть 0, щоб повернутись назад):' 81 | wdw_edit_discount_duration: 'Введіть тривалість знижки (числове значення):' 82 | wdw_edit_discount_more_than_100: Знижка не може бути більшою за 100% або меншою за 0%. 83 | wdw_remove_discount_conf: Ви впевнені, що хочете прибрати знижку %1% відсотків з &l%2%&r? 84 | wdw_custom_names_hint: "Ви можете додати користувацький переклад назви предмета. Зауважте! Ці переклади не відносяться до користувацьких імен предметів, що їх можна додавати за допомогою ковадла, та впливають лише на відображення назв предметів в магазині." 85 | wdw_custom_name_title: Переклад назви предмета 86 | wdw_custom_name_info: |- 87 | ID предмета: %1% 88 | Оригінальна назва: %2% 89 | Переклад: %3% 90 | wdw_add_custom_name_title: Додання перекладу 91 | wdw_add_custom_name_fail: "Для назви цього предмета вже є переклад." 92 | wdw_edit_custom_name_title: Ред. перекладу 93 | wdw_custom_name_hint: "Переклад назви предмета:" 94 | wdw_delete_custom_name_title: Видалення перекладу 95 | wdw_delete_custom_name_conf: "Ви впевнені, що хочете видалити переклад назви цього предмета? Цю дію неможливо скасувати." 96 | 97 | wdw_add_enchantment_title: Додавання зачарувань 98 | wdw_add_enchantment_selector_hint: "Виберіть зачарування:" 99 | wdw_add_enchantment_level_hint: Виберіть рівень (0 щоб повернутися назад) 100 | wdw_manage_enchantments_title: Редагування зачарувань на %1% 101 | wdw_manage_enchantments_text: Оберіть зачарування зі списку, щоб видалити його, або натисніть "+ Додати зачарування". 102 | wdw_manage_enchantments_empty: Цей предмет не має зачарувань 103 | wdw_remove_enchantment_title: Видалення зачарувань 104 | wdw_remove_enchantment_conf: Ви впевнені, що хочете зняти зачарування &l%1%&r з &l%2%&r? 105 | 106 | buy_no_money: Недостатньо грошей для придбання цього предмета. 107 | buy_no_space: Недостатньо вільного місця в інвентарі для придбання цього предмета. 108 | buy_no_space_and_money: Недостатньо грошей і вільного місця в інвентарі для придбання предмета. 109 | error: Сталася помилка. 110 | error_desc: 'Сталася помилка: %1%' 111 | buy_success: Ви успішно придбали %1% шт. &l%2%&r за %3%%4%. 112 | sell_success: Ви успішно продали %1% шт. &l%2%&r за %3%%4%. 113 | log_category_added: Користувач %1% додав нову категорію предметів, доступних для придбання, під назвою %2%. 114 | log_category_deleted: Користувач %1% видалив категорію предметів, доступних для придбання, під назвою %2%. 115 | log_category_renamed: Користувач %1% перейменував категорію предметів, доступних для придбання, під назвою %2% у %3%. 116 | log_buy_item_added: 'Користувач %1% додав %2% (ID: %3%) у список предметів, доступних для придбання, ціна: %4%%5%.' 117 | log_buy_item_added_with_custom_name: 'Користувач %1% додав %2% (оригінальна назва: %3%, ID: %4%) у список предметів, доступних для придбання, ціна: %5%%6%.' 118 | log_buy_item_deleted: 'Користув. %1% видалив %2% (ID: %3%) зі списку предметів, доступних для придбання.' 119 | log_buy_item_edited: 'Користувач %1% відредагував предмет %2%, що доступний для придбання: %3%.' 120 | log_edited_id: змінив ID з %1% на %2% 121 | log_edited_name: змінив назву з %1% на %2% 122 | log_edited_price: змінив ціну з %1%%2% на %3%%2% 123 | log_edited_lore: змінив опис з %1% на %2% 124 | log_added_lore: додав опис (%1%) 125 | log_removed_lore: видалив опис (%1%) 126 | log_added_custom_name: додав коистувацьку назву (%1%) 127 | log_edited_custom_name: змінив користувацьку назву з %1% на %2% 128 | log_removed_custom_name: прибрав користувацьку назву (%1%) 129 | log_discount_added: 'Користувач %1% додав знижку %2%% на %3% (ID: %4%) на %5% %6%.' 130 | log_discount_deleted: 'Користувач %1% видалив знижку на %2% (ID: %3%).' 131 | log_sell_item_added: 'Користувач %1% додав %2% (ID: %3%) до списку предметів, доступних для продажу, ціна: %4%%5%.' 132 | log_sell_item_added_with_custom_name: 'Користувач %1% додав %2% (оригінальна назва: %3%, ID: %4%) до списку предметів, доступних для продажу, ціна: %5%%6%.' 133 | log_sell_item_deleted: 'Користувач %1% видалив %2% (ID: %3%) зі списку предметів, доступних для продажу.' 134 | log_sell_item_edited: 'Користувач %1% відредагував предмет %2%, що доступний для продажу: %3%.' 135 | log_buy_enchantment_added: Користувач %1% додав зачарування %2% %3% на предмет %4% (%5%), що доступний для придбання. 136 | log_sell_enchantment_added: Користувач %1% додав зачарування %2% %3% на предмет %4% (%5%), що доступний для продажу. 137 | log_buy_enchantment_removed: Користувач %1% прибрав зачарування %2% %3% з предмета %4% (%5%), що доступний для придбання. 138 | log_sell_enchantment_removed: Користувач %1% прибрав зачарування %2% %3% з предмета %4% (%5%), що доступний для продажу. 139 | log_bought: 'Гравець %1% придбав %2% шт. %3% (ID: %4%) за %5%%6%.' 140 | log_sold: 'Гравець %1% продав %2% шт. %3% (ID: %4%) за %5%%6%.' 141 | log_translation_added: Гравець %1% додав переклад назви предмета %2% (%3%) - %4%. 142 | log_translation_changed: Гравець %1% змінив переклад назви предмета %2% (%3%) з %4% на %5%. 143 | log_translation_deleted: Гравець %1% видалив переклад назви предмета %2% (%3%). 144 | log_buyable_items_found: Знайдено файл buyList.yml, імпортуємо предмети до бази даних... 145 | log_sellable_items_found: Знайдено файл sellList.yml, імпортуємо предмети до бази даних... 146 | log_translations_found: Знайдено файл customItemNames.yml, імпортуємо переклади до бази даних... 147 | log_buyable_items_imported: Імпортовано %1% категорій та %2% предметів для купівлі, файл buyList.yml видалено. 148 | log_sellable_items_imported: Імпортовано %1% предметів для продажу, файл sellList.yml видалено. 149 | log_all_translations_imported: Імпортовано %1% перекладів, файл customItemNames.yml видалено. 150 | log_import_skipped_translations: Імпортовано %1% перекладів, пропущено %2% перекладів назв тих предметів, для яких вже є переклади. Пропущені переклади збережено в файлі customItemNames.yml. 151 | log_import_failed: Не вдалося імпортувати. 152 | log_reading_nbt_failed: Помилка зчитування NBT тегу предмета з record_id %1% 153 | seconds: секунд 154 | minutes: хвилин 155 | hours: годин 156 | days: днів 157 | months: місяців 158 | infinity: нескіченність -------------------------------------------------------------------------------- /src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: "Trading_Interface" 2 | main: ua.leonidius.trdinterface.Trading 3 | version: ${project.version} 4 | author: Leondius20 5 | url: ${project.url} 6 | api: ["1.0.8"] 7 | description: Shop system based on interface. 8 | permissions: 9 | shop.edit: 10 | description: Editing lists of buyable and sellable items and discounts. 11 | default: op 12 | depend: 13 | - EconomyAPI 14 | - DbLib --------------------------------------------------------------------------------