NEW Players can now issue refunds for trades they've completed within the last 5 minutes
NEW Added more sign-interactions and seperated shift and none-shift interactions (though this might be a bit buggy for bedrock, sorry guys, just nothing I can do about this)
NEW (Experimental) Itemcages: Creating a glass around the previewitem to seperate it more from "drops" if enabled
NEW (Experimental) Static previewitem rotation; Previewitems do not rotate towards players anymore if enabled
IMPROVED Visual clarity of settings menu
IMPROVED Loadbalancer
IMPROVED Modularized some systems like commands (does not affect players, just makes my life easier)
FIXED Pending offers button sometimes not working
FIXED Hologram and previewitem not shifting over when switching from default location to custom location
![]()
NEW Players can create shared shops (Free mode limited to 3 players per shop). In shared mode, players can assign permissions, handle shop parts they have perms for and work together
NEW Shop grouping. Shops can be grouped together for easier management
NEW Shop browser with featured slots (toggleable). If enabled, there is a server-wide blind bidding after which the winners will have one slot to advertise their shops in the global browser.
NEW Item-preview custom offset (with toggle and default preset)
NEW Optional creation and upkeep cost systems
IMPROVED Settings menu (split by category, toggles and with pages)
FIXED Permission check firing too often, causing 0.05% more server load than necessary (Yes, I take the "best optimized shop" thing very serious).
FIXED Automigrator duping lore lines when checking for old configs
I have made an (AI) Summary of the updated API for anyone that wants to use it. Please don't come at me for not hosting in publicly, just use reflections as described in the guide. I can't be arsed to manage the API library via maven.
https://www.markdownpaste.com/document/tiny-markets-api-1711-latest
I am very sorry to anyone that was affected by the automigrator duping lore lines. DM me or open a ticket in Discord and I'll personally sort this out for you!
FIX Counteroffer menu for item-trades blocking all inventory interactions, effectively speaking blocking the player from using the "Offer different item" option. (silly bug)
NEW Users can now create counteroffers, manage them easier and see pending offers. This comes with automatic nudges about unclaimed trades and new offers
NEW Toggle for admins to allow teleporting to shops (with warmup) to shops from browser and search function
NEW Global Browser for shops by category or player
NEW Categoryeditor for admins for browser
NEW Automatic migration from config.yml and messages.yml (premium only) when new update drops. The plugin will copy over your settings
IMPROVED Search is now more accurate and offers better filtering
NEW Logging via DiscordSRV (experimental)
NEW config.yml now contains a link to all permissions (https://www.markdownpaste.com/document/permissions-tiny-markets-v177)
NEW Better documentation and limit info on permissions
FIXED Some messages not loading fully
Reducing the amount of rows a menu has in Premium-mode does not work. I am working on this
NEW Players can make counter offers for shops (toggleable global and per shop)
NEW Players can offer bulk-purchase discounts i.e. 5% off from an order of 1000 items or more (default and permission based limits)
NEW Initial support for dynmap (though markers are having issues rendering for now - experimental)
NEW Support for plot-squared
NEW Claimables menu - unclaimed offers that got accepted land here
Improved Adding more message configs to messages.yml for bossbar and actionmar messages etc
Improved Better shop prechaching for statistics and price overviews
And some more I forgot to note down... will be appended in the next update info
NEW Discord webhooks (fully working including batchmode or instant mode
NEW Public API (shade jar into your plugin as lib and use reflection. See below for list of api methods and examples.
IMPROVED Fixed a bug with migration from plugin Shop (https://www.spigotmc.org/resources/shop-the-intuitive-shop-plugin.9628/) caused by the owner storing the location of shops not as the container but the sign... and in the wrong format... and not always the same depending on what side the container is facing.Seriously, just avoid that plugin, its utter dog****...
API:
YAML:Available methods: getAllShops() - Get all registered shops getShopById(long) - Get shop by ID getShopAt(Location) - Get shop at location getShopsByOwner(UUID) - Get all shops by owner getShopCount(UUID) - Count shops owned by player isShop(Location) - Check if location has a shop getMaxShopsFor(Player) - Get max shops for player setEconomyProvider(Economy) - Set custom economy getEconomyProvider() - Get current economy firePrePurchaseEvent(...) - Fire purchase event firePreSellEvent(...) - Fire sell event getVersion() - Get plugin version isPremium() - Check if premium getPlugin() - Get raw plugin instance
Examples:
Java:@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onShopSell(ShopPreSellEvent event) { if (!plugin.isLoggingEnabled() || !plugin.isConsoleLoggingEnabled()) { return; } Shop shop = event.getShop(); Player seller = event.getSeller(); int amount = event.getAmount(); double totalPrice = event.getTotalPrice(); String itemName = getItemName(shop); String ownerName = shop.ownerName(); plugin.getLogger().info(String.format( "[SELL] %s sold %dx %s to %s's shop for %.2f", seller.getName(), amount, itemName, ownerName, totalPrice )); }
Java:@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) public void onShopPurchase(ShopPrePurchaseEvent event) { if (!plugin.isLoggingEnabled() || !plugin.isConsoleLoggingEnabled()) { return; } Shop shop = event.getShop(); Player buyer = event.getBuyer(); int amount = event.getAmount(); double totalPrice = event.getTotalPrice(); String itemName = getItemName(shop); String ownerName = shop.ownerName(); plugin.getLogger().info(String.format( "[PURCHASE] %s bought %dx %s from %s's shop for %.2f", buyer.getName(), amount, itemName, ownerName, totalPrice )); }
Java:package me.netizdendev.marketsHooker; import me.netizdendev.marketsHooker.config.ConfigManager; import me.netizdendev.marketsHooker.listeners.ShopListener; import me.netizdendev.tinyMarkets.api.TinyMarketsAPI; import org.bukkit.Bukkit; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.scheduler.BukkitRunnable; public final class MarketsHooker extends JavaPlugin { private ConfigManager configManager; private TinyMarketsAPI tinyMarketsAPI; private boolean hooked = false; @Override public void onEnable() { // Initialize configuration configManager = new ConfigManager(this); configManager.loadConfig(); // TinyMarkets is a Paper plugin, so it may not be enabled yet when this Bukkit plugin enables. // We need to wait for the server to finish loading, then check for TinyMarkets. getLogger().info("Waiting for TinyMarkets to be available..."); // Schedule a delayed task to hook into TinyMarkets after server is fully loaded new BukkitRunnable() { private int attempts = 0; private final int maxAttempts = 20; // Try for 10 seconds (20 * 10 ticks = 200 ticks = 10 seconds) @Override public void run() { attempts++; // Check if TinyMarkets API is available if (TinyMarketsAPI.isAvailable()) { tinyMarketsAPI = TinyMarketsAPI.getInstance(); hooked = true; // Register event listeners Bukkit.getPluginManager().registerEvents(new ShopListener(MarketsHooker.this), MarketsHooker.this); getLogger().info("MarketsHooker hooked into TinyMarkets v" + tinyMarketsAPI.getVersion() + " successfully!"); getLogger().info("Logging module: " + (isLoggingEnabled() ? "ENABLED" : "DISABLED")); this.cancel(); return; } // If we've exceeded max attempts, give up if (attempts >= maxAttempts) { getLogger().warning("TinyMarkets API not available after " + maxAttempts + " attempts. MarketsHooker will not function."); getLogger().warning("Please ensure TinyMarkets is installed and enabled."); this.cancel(); } } }.runTaskTimer(this, 10L, 10L); // Start after 10 ticks, repeat every 10 ticks (0.5 seconds) } @Override public void onDisable() { getLogger().info("MarketsHooker disabled!" + (hooked ? " (was hooked to TinyMarkets)" : " (was not hooked)")); } public boolean isHooked() { return hooked; } public boolean isLoggingEnabled() { return configManager.isLoggingEnabled(); } public boolean isConsoleLoggingEnabled() { return configManager.isConsoleLoggingEnabled(); } public TinyMarketsAPI getTinyMarketsAPI() { return tinyMarketsAPI; } public ConfigManager getConfigManager() { return configManager; } }
