Second+third review pass (2026-07-10/11): security and completeness fixes, public-release polish

This commit is contained in:
2026-07-11 13:59:33 +01:00
parent fe8dc78d0f
commit bc6e2296c6
34 changed files with 226 additions and 203 deletions
Vendored
BIN
View File
Binary file not shown.
+31
View File
@@ -0,0 +1,31 @@
# Build output
target/
build/
.gradle/
out/
bin/
*.class
# Node (remnants of any old embedded web-panel)
node_modules/
package-lock.json
# IDE / tooling
.idea/
*.iml
.vscode/
.claude/
.settings/
.classpath
.project
# OS
.DS_Store
Thumbs.db
# Local / logs
*.log
build_output.txt
dependency-reduced-pom.xml
run/
logs/
+23 -26
View File
@@ -1,43 +1,43 @@
# CommunityMarket # CommunityMarket
[![Modrinth Downloads](https://img.shields.io/modrinth/dt/communitymarket?logo=modrinth)](https://modrinth.com/plugin/communitymarket) [![Modrinth Downloads](https://img.shields.io/modrinth/dt/carrageis-communitymarket?logo=modrinth)](https://modrinth.com/plugin/carrageis-communitymarket)
[![GitHub License](https://img.shields.io/github/license/henrique/CommunityMarket)](LICENSE) [![GitHub License](https://img.shields.io/github/license/henrique/CommunityMarket)](LICENSE)
A professional, production-ready **GUI-only marketplace plugin** for Minecraft Paper 1.21+. A professional, production-ready **GUI-only marketplace plugin** for Minecraft Paper 1.21+.
Players can create fixed-price listings and auctions, browse, buy, bid, claim items, and withdraw earnings — all through intuitive GUIs. **No complex commands to learn!** Players can create fixed-price listings and auctions, browse, buy, bid, claim items, and withdraw earnings — all through intuitive GUIs. **No complex commands to learn!**
## ✨ Features Features
### 🛒 Fixed-Price Market Fixed-Price Market
- Create listings with custom prices and durations - Create listings with custom prices and durations
- Browse paginated listings with sorting - Browse paginated listings with sorting
- Safe atomic purchases to prevent double-buying - Safe atomic purchases to prevent double-buying
- Configurable taxes on sales - Configurable taxes on sales
### 🔨 Auction System Auction System
- Start auctions with minimum bid and optional buyout price - Start auctions with minimum bid and optional buyout price
- **Anti-snipe protection** extends auction when bids arrive near the end - **Anti-snipe protection** extends auction when bids arrive near the end
- Bid history and automatic outbid notifications - Bid history and automatic outbid notifications
- Safe handling of auction endings and payouts - Safe handling of auction endings and payouts
### 📦 Claim Storage Claim Storage
- Items from expired listings go to claim storage - Items from expired listings go to claim storage
- Won auction items are safely delivered - Won auction items are safely delivered
- Handles full inventories gracefully - Handles full inventories gracefully
### 💰 Earnings Management Earnings Management
- Pending earnings from sales accumulate - Pending earnings from sales accumulate
- Withdraw all earnings at once - Withdraw all earnings at once
- Complete transaction history - Complete transaction history
### 🔐 Admin Features (GUI-based) Admin Features (GUI-based)
- View all listings and auctions - View all listings and auctions
- Remove any listing or cancel auctions - Remove any listing or cancel auctions
- Force-end auctions - Force-end auctions
- Reload configuration in-game - Reload configuration in-game
### 🎮 Intuitive GUI Flow Intuitive GUI Flow
The creation flow for listings and auctions: The creation flow for listings and auctions:
1. **Main Menu** - Central hub for all actions 1. **Main Menu** - Central hub for all actions
2. **Select Item** - Click an item from your inventory 2. **Select Item** - Click an item from your inventory
@@ -45,7 +45,7 @@ The creation flow for listings and auctions:
4. **Settings** - Set price and duration with easy click-to-adjust controls 4. **Settings** - Set price and duration with easy click-to-adjust controls
5. **Confirm** - Review and create your listing/auction 5. **Confirm** - Review and create your listing/auction
## 📋 Requirements Requirements
| Requirement | Version | | Requirement | Version |
|-------------|---------| |-------------|---------|
@@ -57,23 +57,23 @@ The creation flow for listings and auctions:
CommunityMarket supports two economy configurations: CommunityMarket supports two economy configurations:
1. **Vault + Economy Plugin** (Recommended) 1. **Vault + Economy Plugin** (Recommended)
- Install [Vault](https://modrinth.com/plugin/vault-2.0-economy-plugins) - Install [VaultUnlocked](https://modrinth.com/plugin/vaultunlocked)
- Install an economy plugin: [EssentialsX](https://essentialsx.net/), CMI, or any Vault-compatible economy - Install an economy plugin: [EssentialsX](https://essentialsx.net/), CMI, or any Vault-compatible economy
2. **EssentialsX Standalone** (Fallback) 2. **EssentialsX Standalone** (Fallback)
- Install [EssentialsX](https://essentialsx.net/) with economy enabled - Install [EssentialsX](https://essentialsx.net/) with economy enabled
- CommunityMarket will use EssentialsX directly if Vault is not present - CommunityMarket will use EssentialsX directly if Vault is not present
## 📥 Installation Installation
1. Download the latest `CommunityMarket-x.x.x.jar` from [Modrinth](https://modrinth.com/plugin/communitymarket) 1. Download the latest `CommunityMarket-x.x.x.jar` from [Modrinth](https://modrinth.com/plugin/carrageis-communitymarket)
2. Place it in your server's `plugins/` folder 2. Place it in your server's `plugins/` folder
3. Ensure you have an economy system installed (see above) 3. Ensure you have an economy system installed (see above)
4. Start or restart your server 4. Start or restart your server
5. Edit `plugins/CommunityMarket/config.yml` as needed 5. Edit `plugins/CommunityMarket/config.yml` as needed
6. Use `/market` to open the marketplace! 6. Use `/market` to open the marketplace!
## 🎮 Commands Commands
| Command | Alias | Description | Permission | | Command | Alias | Description | Permission |
|---------|-------|-------------|------------| |---------|-------|-------------|------------|
@@ -81,7 +81,7 @@ CommunityMarket supports two economy configurations:
**That's it!** Everything else is done through GUIs. **That's it!** Everything else is done through GUIs.
## 🔒 Permissions Permissions
| Permission | Description | Default | | Permission | Description | Default |
|------------|-------------|---------| |------------|-------------|---------|
@@ -94,11 +94,8 @@ CommunityMarket supports two economy configurations:
| `communitymarket.claim` | Claim items from storage | everyone | | `communitymarket.claim` | Claim items from storage | everyone |
| `communitymarket.withdraw` | Withdraw earnings | everyone | | `communitymarket.withdraw` | Withdraw earnings | everyone |
| `communitymarket.admin` | Access admin functions | op | | `communitymarket.admin` | Access admin functions | op |
| `communitymarket.admin.viewall` | View all listings/auctions | op |
| `communitymarket.admin.remove` | Remove any listing/auction | op |
| `communitymarket.admin.reload` | Reload configuration | op |
## ⚙️ Configuration Configuration
### config.yml Highlights ### config.yml Highlights
@@ -148,7 +145,7 @@ gui:
Language files are located in `plugins/CommunityMarket/lang/` and can be customized. Language files are located in `plugins/CommunityMarket/lang/` and can be customized.
## 🔧 Troubleshooting Troubleshooting
### "No compatible economy provider found!" ### "No compatible economy provider found!"
@@ -156,7 +153,7 @@ This error appears when CommunityMarket cannot find an economy system.
**Solutions:** **Solutions:**
1. **Install Vault + an economy plugin:** 1. **Install Vault + an economy plugin:**
- Download [Vault]([https://www.spigotmc.org/resources/vault.34315/](https://modrinth.com/plugin/vault-2.0-economy-plugins)) - Download [VaultUnlocked](https://modrinth.com/plugin/vaultunlocked)
- Download [EssentialsX](https://essentialsx.net/) or another economy plugin - Download [EssentialsX](https://essentialsx.net/) or another economy plugin
- Restart your server - Restart your server
@@ -190,20 +187,20 @@ database:
password: your_password password: your_password
``` ```
## 📊 API API
CommunityMarket does not currently provide a public API. If you need integration capabilities, please open an issue on GitHub. CommunityMarket does not currently provide a public API. If you need integration capabilities, please open an issue on GitHub.
## 🤝 Support Support
- **Issues & Bug Reports:** [GitHub Issues](https://github.com/henrique/CommunityMarket/issues) - **Issues & Bug Reports:** [GitHub Issues](https://github.com/henriquescrrrr/carrageis-communitymarket/issues)
- **Feature Requests:** [GitHub Issues](https://github.com/henrique/CommunityMarket/issues) - **Feature Requests:** [GitHub Issues](https://github.com/henriquescrrrr/carrageis-communitymarket/issues)
## 📜 License License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## 🙏 Credits Credits
- Built for the Paper/Spigot community - Built for the Paper/Spigot community
- Uses [Vault](https://github.com/MilkBowl/VaultAPI) for economy integration - Uses [Vault](https://github.com/MilkBowl/VaultAPI) for economy integration
+8
View File
@@ -39,6 +39,14 @@
</relocation> </relocation>
</relocations> </relocations>
<minimizeJar>true</minimizeJar> <minimizeJar>true</minimizeJar>
<filters>
<filter>
<artifact>org.xerial:sqlite-jdbc</artifact>
<includes>
<include>**</include>
</includes>
</filter>
</filters>
</configuration> </configuration>
</execution> </execution>
</executions> </executions>
+14
View File
@@ -95,6 +95,20 @@
</relocation> </relocation>
</relocations> </relocations>
<minimizeJar>true</minimizeJar> <minimizeJar>true</minimizeJar>
<!--
The SQLite driver is loaded by class name at runtime
(setDriverClassName("org.sqlite.JDBC")), so minimizeJar's static
reachability analysis cannot see it and would strip it, breaking the
default SQLite backend. Force its classes (and native libs) to be kept.
-->
<filters>
<filter>
<artifact>org.xerial:sqlite-jdbc</artifact>
<includes>
<include>**</include>
</includes>
</filter>
</filters>
</configuration> </configuration>
</execution> </execution>
</executions> </executions>
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
@@ -124,8 +124,11 @@ public class ConfigManager {
// Economy settings // Economy settings
currencyFormat = config.getString("economy.currency-format", "$#,##0.00"); currencyFormat = config.getString("economy.currency-format", "$#,##0.00");
currencySymbol = config.getString("economy.currency-symbol", "$"); currencySymbol = config.getString("economy.currency-symbol", "$");
marketTax = config.getDouble("economy.taxes.market-tax", 5.0); // Clamp taxes to [0, 100]. A tax > 100 would make seller earnings negative
auctionTax = config.getDouble("economy.taxes.auction-tax", 7.5); // (price * (1 - tax/100)) which the deposit path would then mint/refuse - a config
// mistake must never be able to create or destroy money.
marketTax = clampPercent(config.getDouble("economy.taxes.market-tax", 5.0));
auctionTax = clampPercent(config.getDouble("economy.taxes.auction-tax", 7.5));
// Market settings // Market settings
maxListingsPerPlayer = config.getInt("market.max-listings-per-player", 20); maxListingsPerPlayer = config.getInt("market.max-listings-per-player", 20);
@@ -272,6 +275,23 @@ public class ConfigManager {
return blacklistedMaterials.contains(material); return blacklistedMaterials.contains(material);
} }
/**
* Clamps a percentage value to the valid [0, 100] range.
* Non-finite values (NaN/Infinity from a malformed config) fall back to 0.
*/
private double clampPercent(double value) {
if (Double.isNaN(value) || Double.isInfinite(value)) {
plugin.getLogger().warning("Invalid tax percentage in config; defaulting to 0.");
return 0.0;
}
if (value < 0.0) return 0.0;
if (value > 100.0) {
plugin.getLogger().warning("Tax percentage " + value + " exceeds 100; clamping to 100.");
return 100.0;
}
return value;
}
/** /**
* Checks if text contains blacklisted keywords * Checks if text contains blacklisted keywords
*/ */
@@ -36,8 +36,8 @@ public class MessageManager {
public void reload() { public void reload() {
messageCache.clear(); messageCache.clear();
// Get language from config // Get language from config (default pt_PT; en_US remains bundled as a fallback)
currentLanguage = plugin.getConfig().getString("language", "en_US"); currentLanguage = plugin.getConfig().getString("language", "pt_PT");
// Save default language files // Save default language files
saveDefaultLanguageFiles(); saveDefaultLanguageFiles();
@@ -349,25 +349,45 @@ public class CreateAuctionGui implements MarketGui {
// Create the auction // Create the auction
ItemStack auctionItem = selectedItem.clone(); ItemStack auctionItem = selectedItem.clone();
int amount = auctionItem.getAmount();
// From here an async creation is in flight; block further confirms until it finishes. // From here an async creation is in flight; block further confirms until it finishes.
processing = true; processing = true;
// Reserve the items NOW, atomically on the main thread, BEFORE the async DB write.
// Removing after the async round-trip is a dupe window: during the round-trip the
// player could drop/stash/hand off the items (the auction is built from a clone and
// does not need the live items), leaving them with both the items AND an auction that
// delivers the item to the winner. Remove-first + refund-on-failure closes that window.
if (!InventoryUtil.removeItem(player, auctionItem, amount)) {
processing = false;
player.sendMessage(msgManager.getPrefixed("messages.item-no-longer-available"));
SoundUtil.playSound(player, plugin.getConfigManager().getErrorSound());
new ItemSelectionGui(plugin, guiManager, ItemSelectionGui.SelectionMode.AUCTION).open(player);
return;
}
plugin.getTransactionService().createAuctionTransaction( plugin.getTransactionService().createAuctionTransaction(
player, auctionItem, startPrice, buyoutPrice, durationHours player, auctionItem, startPrice, buyoutPrice, durationHours
).thenAccept(result -> { ).thenAccept(result -> {
Bukkit.getScheduler().runTask(plugin, () -> { Bukkit.getScheduler().runTask(plugin, () -> {
processing = false; processing = false;
if (result.isSuccess()) { if (result.isSuccess()) {
// Remove items from inventory AFTER successful creation
InventoryUtil.removeItem(player, auctionItem, auctionItem.getAmount());
player.sendMessage(msgManager.getPrefixed("messages.auction-created", player.sendMessage(msgManager.getPrefixed("messages.auction-created",
"id", String.valueOf(result.getId()))); "id", String.valueOf(result.getId())));
SoundUtil.playSound(player, plugin.getConfigManager().getSuccessSound()); SoundUtil.playSound(player, plugin.getConfigManager().getSuccessSound());
player.closeInventory(); player.closeInventory();
guiManager.openMainMenu(player); guiManager.openMainMenu(player);
} else { } else {
// Creation failed AFTER we removed the items - give them back so nothing is lost.
ItemStack refund = auctionItem.clone();
refund.setAmount(amount);
ItemStack leftover = InventoryUtil.giveItem(player, refund);
if (leftover != null) {
plugin.getClaimService().addClaimItem(player.getUniqueId(), leftover,
pt.henrique.communityMarket.model.ClaimItem.ClaimReason.ADMIN_RETURN,
"Auction creation failed");
}
player.sendMessage(msgManager.getPrefixed("messages." + result.getErrorKey())); player.sendMessage(msgManager.getPrefixed("messages." + result.getErrorKey()));
SoundUtil.playSound(player, plugin.getConfigManager().getErrorSound()); SoundUtil.playSound(player, plugin.getConfigManager().getErrorSound());
} }
@@ -298,21 +298,41 @@ public class CreateListingGui implements MarketGui {
// From here an async creation is in flight; block further confirms until it finishes. // From here an async creation is in flight; block further confirms until it finishes.
processing = true; processing = true;
// Reserve the items NOW, atomically on the main thread, BEFORE the async DB write.
// Removing after the async round-trip is a dupe window: during the round-trip the
// player could drop/stash/hand off the items (the listing is built from a clone and
// does not need the live items), leaving them with both the items AND a listing that
// pays out. Remove-first + refund-on-failure closes that window.
if (!InventoryUtil.removeItem(player, listItem, amount)) {
// Couldn't take the full amount (item moved between the check and here) - abort.
processing = false;
player.sendMessage(msgManager.getPrefixed("messages.item-no-longer-available"));
SoundUtil.playSound(player, plugin.getConfigManager().getErrorSound());
new ItemSelectionGui(plugin, guiManager, ItemSelectionGui.SelectionMode.LISTING).open(player);
return;
}
plugin.getTransactionService().createListingTransaction( plugin.getTransactionService().createListingTransaction(
player, listItem, amount, price, durationHours player, listItem, amount, price, durationHours
).thenAccept(result -> { ).thenAccept(result -> {
Bukkit.getScheduler().runTask(plugin, () -> { Bukkit.getScheduler().runTask(plugin, () -> {
processing = false; processing = false;
if (result.isSuccess()) { if (result.isSuccess()) {
// Remove items from inventory AFTER successful creation
InventoryUtil.removeItem(player, listItem, amount);
player.sendMessage(msgManager.getPrefixed("messages.listing-created", player.sendMessage(msgManager.getPrefixed("messages.listing-created",
"id", String.valueOf(result.getId()))); "id", String.valueOf(result.getId())));
SoundUtil.playSound(player, plugin.getConfigManager().getSuccessSound()); SoundUtil.playSound(player, plugin.getConfigManager().getSuccessSound());
player.closeInventory(); player.closeInventory();
guiManager.openMainMenu(player); guiManager.openMainMenu(player);
} else { } else {
// Creation failed AFTER we removed the items - give them back so nothing is lost.
ItemStack refund = listItem.clone();
refund.setAmount(amount);
ItemStack leftover = InventoryUtil.giveItem(player, refund);
if (leftover != null) {
plugin.getClaimService().addClaimItem(player.getUniqueId(), leftover,
pt.henrique.communityMarket.model.ClaimItem.ClaimReason.ADMIN_RETURN,
"Listing creation failed");
}
player.sendMessage(msgManager.getPrefixed("messages." + result.getErrorKey())); player.sendMessage(msgManager.getPrefixed("messages." + result.getErrorKey()));
SoundUtil.playSound(player, plugin.getConfigManager().getErrorSound()); SoundUtil.playSound(player, plugin.getConfigManager().getErrorSound());
} }
@@ -48,111 +48,24 @@ public class HelpGui implements MarketGui {
inventory.setItem(i, filler); inventory.setItem(i, filler);
} }
// Help content // Help content (localized). Rendered as the book's lore so the Help screen
// respects the configured language instead of showing hardcoded English.
List<String> helpContent = msgManager.getList("help.content"); List<String> helpContent = msgManager.getList("help.content");
// Main help book // Main help book with the localized explanation of every feature
inventory.setItem(4, new ItemBuilder(Material.WRITTEN_BOOK) inventory.setItem(22, new ItemBuilder(Material.WRITTEN_BOOK)
.name(msgManager.getRaw("help.title")) .name(msgManager.getRaw("help.title"))
.lore(helpContent)
.build()); .build());
// Feature explanations // Tax info (values are dynamic; labels come from the language file)
inventory.setItem(19, new ItemBuilder(Material.CHEST)
.name("&aBrowse Market")
.lore(
"&7View all fixed-price listings",
"&7from other players.",
"",
"&7Click on items to purchase them."
)
.build());
inventory.setItem(20, new ItemBuilder(Material.GOLD_INGOT)
.name("&6Browse Auctions")
.lore(
"&7View all active auctions.",
"",
"&eLeft-click &7to place a bid",
"&eRight-click &7to buyout (if available)"
)
.build());
inventory.setItem(21, new ItemBuilder(Material.WRITABLE_BOOK)
.name("&eCreate Listing")
.lore(
"&7Sell items at a fixed price.",
"",
"&71. Place your item in the slot",
"&72. Set the price",
"&73. Choose duration",
"&74. Click confirm"
)
.build());
inventory.setItem(22, new ItemBuilder(Material.GOLDEN_HELMET)
.name("&eCreate Auction")
.lore(
"&7Auction items to the highest bidder.",
"",
"&71. Place your item in the slot",
"&72. Set starting price",
"&73. Optionally set buyout",
"&74. Choose duration",
"&75. Click confirm"
)
.build());
inventory.setItem(23, new ItemBuilder(Material.BOOK)
.name("&bMy Listings")
.lore(
"&7View your active listings.",
"",
"&7Click on a listing to cancel it.",
"&7Cancelled items go to claim storage."
)
.build());
inventory.setItem(24, new ItemBuilder(Material.CLOCK)
.name("&bMy Auctions")
.lore(
"&7View your active auctions.",
"",
"&7You can only cancel auctions",
"&7that have no bids yet."
)
.build());
inventory.setItem(25, new ItemBuilder(Material.ENDER_CHEST)
.name("&dClaim Items")
.lore(
"&7Collect items waiting for you:",
"",
"&7- Expired listings",
"&7- Cancelled listings",
"&7- Won auctions",
"&7- Auction refunds"
)
.build());
inventory.setItem(31, new ItemBuilder(Material.EMERALD)
.name("&aEarnings")
.lore(
"&7Withdraw money from sales.",
"",
"&7When you sell something, the money",
"&7goes to pending earnings first.",
"&7Withdraw it here."
)
.build());
// Tax info
inventory.setItem(40, new ItemBuilder(Material.GOLD_NUGGET) inventory.setItem(40, new ItemBuilder(Material.GOLD_NUGGET)
.name("&6Tax Information") .name(msgManager.getRaw("help.tax-title"))
.lore( .lore(
"&7Market Tax: &f" + plugin.getConfigManager().getMarketTax() + "%", msgManager.getRaw("help.tax-market").replace("{tax}", String.valueOf(plugin.getConfigManager().getMarketTax())),
"&7Auction Tax: &f" + plugin.getConfigManager().getAuctionTax() + "%", msgManager.getRaw("help.tax-auction").replace("{tax}", String.valueOf(plugin.getConfigManager().getAuctionTax())),
"", "",
"&7Taxes are deducted from seller earnings." msgManager.getRaw("help.tax-note")
) )
.build()); .build());
+1 -1
View File
@@ -4,7 +4,7 @@
# ============================================ # ============================================
# Language setting (available: en_US, pt_PT) # Language setting (available: en_US, pt_PT)
language: en_US language: pt_PT
# Database Configuration # Database Configuration
database: database:
+8
View File
@@ -45,12 +45,16 @@ messages:
claim-empty: "&eYou have no items to claim." claim-empty: "&eYou have no items to claim."
claim-inventory-full: "&cYour inventory is full! Please make space." claim-inventory-full: "&cYour inventory is full! Please make space."
claim-all-success: "&aClaimed {count} items!" claim-all-success: "&aClaimed {count} items!"
claim-items: "&eYou have &6{count}&e item(s) waiting to be claimed. Use /market to claim them."
# Earnings Messages # Earnings Messages
earnings-withdrawn: "&aWithdrew {amount}! New balance: {balance}" earnings-withdrawn: "&aWithdrew {amount}! New balance: {balance}"
earnings-empty: "&eYou have no pending earnings." earnings-empty: "&eYou have no pending earnings."
earnings-balance: "&aYour pending earnings: {amount}" earnings-balance: "&aYour pending earnings: {amount}"
# Generic
failed: "&cSomething went wrong. Please try again."
# Item Validation # Item Validation
invalid-item: "&cPlease select a valid item." invalid-item: "&cPlease select a valid item."
item-no-longer-available: "&cThe selected item is no longer in your inventory." item-no-longer-available: "&cThe selected item is no longer in your inventory."
@@ -445,4 +449,8 @@ help:
- "" - ""
- "&7&oTip: All actions are done through GUIs!" - "&7&oTip: All actions are done through GUIs!"
- "&7&oJust click on buttons to navigate." - "&7&oJust click on buttons to navigate."
tax-title: "&6Tax Information"
tax-market: "&7Market Tax: &f{tax}%"
tax-auction: "&7Auction Tax: &f{tax}%"
tax-note: "&7Taxes are deducted from seller earnings."
+8
View File
@@ -45,12 +45,16 @@ messages:
claim-empty: "&eNão tens itens para reclamar." claim-empty: "&eNão tens itens para reclamar."
claim-inventory-full: "&cO teu inventário está cheio! Por favor liberta espaço." claim-inventory-full: "&cO teu inventário está cheio! Por favor liberta espaço."
claim-all-success: "&aReclamaste {count} itens!" claim-all-success: "&aReclamaste {count} itens!"
claim-items: "&eTens &6{count}&e item(ns) por reclamar. Usa /market para os reclamar."
# Mensagens de Ganhos # Mensagens de Ganhos
earnings-withdrawn: "&aLevantaste {amount}! Novo saldo: {balance}" earnings-withdrawn: "&aLevantaste {amount}! Novo saldo: {balance}"
earnings-empty: "&eNão tens ganhos pendentes." earnings-empty: "&eNão tens ganhos pendentes."
earnings-balance: "&aOs teus ganhos pendentes: {amount}" earnings-balance: "&aOs teus ganhos pendentes: {amount}"
# Genérico
failed: "&cAlgo correu mal. Tenta novamente."
# Validação de Itens # Validação de Itens
invalid-item: "&cPor favor seleciona um item válido." invalid-item: "&cPor favor seleciona um item válido."
item-no-longer-available: "&cO item selecionado já não está no teu inventário." item-no-longer-available: "&cO item selecionado já não está no teu inventário."
@@ -445,4 +449,8 @@ help:
- "" - ""
- "&7&oDica: Todas as ações são feitas através de GUIs!" - "&7&oDica: Todas as ações são feitas através de GUIs!"
- "&7&oBasta clicar nos botões para navegar." - "&7&oBasta clicar nos botões para navegar."
tax-title: "&6Informação de Taxas"
tax-market: "&7Taxa do Mercado: &f{tax}%"
tax-auction: "&7Taxa dos Leilões: &f{tax}%"
tax-note: "&7As taxas são deduzidas dos ganhos do vendedor."
+2 -18
View File
@@ -4,7 +4,7 @@ main: pt.henrique.communityMarket.CommunityMarket
api-version: '1.21' api-version: '1.21'
description: A GUI-only marketplace plugin for fixed-price listings and auctions description: A GUI-only marketplace plugin for fixed-price listings and auctions
author: Henrique author: Henrique
website: https://github.com/henrique/CommunityMarket website: https://github.com/henriquescrrrr/carrageis-communitymarket
# Soft dependencies - plugin will detect and use these if available # Soft dependencies - plugin will detect and use these if available
softdepend: softdepend:
@@ -63,21 +63,5 @@ permissions:
default: true default: true
communitymarket.admin: communitymarket.admin:
description: Allows access to admin functions description: Allows access to admin functions (view all, remove listings, reload)
default: op
children:
communitymarket.admin.viewall: true
communitymarket.admin.remove: true
communitymarket.admin.reload: true
communitymarket.admin.viewall:
description: Allows viewing all listings/auctions
default: op
communitymarket.admin.remove:
description: Allows removing any listing or auction
default: op
communitymarket.admin.reload:
description: Allows reloading configuration
default: op default: op
Binary file not shown.
@@ -4,15 +4,15 @@ pt/henrique/communityMarket/config/MessageManager.class
pt/henrique/communityMarket/model/PendingEarnings.class pt/henrique/communityMarket/model/PendingEarnings.class
pt/henrique/communityMarket/gui/AdminGui$AdminListingsGui.class pt/henrique/communityMarket/gui/AdminGui$AdminListingsGui.class
pt/henrique/communityMarket/model/Auction.class pt/henrique/communityMarket/model/Auction.class
pt/henrique/communityMarket/economy/EconomyManager$EconomyAdapter.class
pt/henrique/communityMarket/listener/PlayerListener.class pt/henrique/communityMarket/listener/PlayerListener.class
pt/henrique/communityMarket/economy/EconomyManager$EconomyAdapter.class
pt/henrique/communityMarket/gui/MarketGui.class pt/henrique/communityMarket/gui/MarketGui.class
pt/henrique/communityMarket/service/AuctionService.class pt/henrique/communityMarket/service/AuctionService.class
pt/henrique/communityMarket/util/ItemSerializer.class pt/henrique/communityMarket/util/ItemSerializer.class
pt/henrique/communityMarket/gui/MainMenuGui.class
pt/henrique/communityMarket/service/EarningsService$WithdrawResult.class pt/henrique/communityMarket/service/EarningsService$WithdrawResult.class
pt/henrique/communityMarket/gui/ConfirmationGui.class pt/henrique/communityMarket/gui/MainMenuGui.class
pt/henrique/communityMarket/service/ListingService.class pt/henrique/communityMarket/service/ListingService.class
pt/henrique/communityMarket/gui/ConfirmationGui.class
pt/henrique/communityMarket/gui/HelpGui.class pt/henrique/communityMarket/gui/HelpGui.class
pt/henrique/communityMarket/db/DatabaseManager.class pt/henrique/communityMarket/db/DatabaseManager.class
pt/henrique/communityMarket/gui/QuantitySelectGui$QuantityCallback.class pt/henrique/communityMarket/gui/QuantitySelectGui$QuantityCallback.class
@@ -22,12 +22,12 @@ pt/henrique/communityMarket/model/Bid.class
pt/henrique/communityMarket/service/ClaimService.class pt/henrique/communityMarket/service/ClaimService.class
pt/henrique/communityMarket/task/ExpiredListingTask.class pt/henrique/communityMarket/task/ExpiredListingTask.class
pt/henrique/communityMarket/gui/NumberInputGui$NumberInputCallback.class pt/henrique/communityMarket/gui/NumberInputGui$NumberInputCallback.class
pt/henrique/communityMarket/gui/MyAuctionsGui.class
pt/henrique/communityMarket/service/ClaimService$ClaimResult.class pt/henrique/communityMarket/service/ClaimService$ClaimResult.class
pt/henrique/communityMarket/gui/ConfirmationGui$ConfirmCallback.class pt/henrique/communityMarket/gui/MyAuctionsGui.class
pt/henrique/communityMarket/CommunityMarket.class pt/henrique/communityMarket/CommunityMarket.class
pt/henrique/communityMarket/gui/BrowseMarketGui.class pt/henrique/communityMarket/gui/ConfirmationGui$ConfirmCallback.class
pt/henrique/communityMarket/model/ClaimItem$ClaimReason.class pt/henrique/communityMarket/model/ClaimItem$ClaimReason.class
pt/henrique/communityMarket/gui/BrowseMarketGui.class
pt/henrique/communityMarket/model/Auction$AuctionStatus.class pt/henrique/communityMarket/model/Auction$AuctionStatus.class
pt/henrique/communityMarket/util/SoundUtil.class pt/henrique/communityMarket/util/SoundUtil.class
pt/henrique/communityMarket/gui/BrowseMarketGui$1.class pt/henrique/communityMarket/gui/BrowseMarketGui$1.class
@@ -39,13 +39,13 @@ pt/henrique/communityMarket/command/MarketCommand.class
pt/henrique/communityMarket/listener/GuiListener$1.class pt/henrique/communityMarket/listener/GuiListener$1.class
pt/henrique/communityMarket/service/AuctionService$BidResult.class pt/henrique/communityMarket/service/AuctionService$BidResult.class
pt/henrique/communityMarket/gui/CreateListingGui.class pt/henrique/communityMarket/gui/CreateListingGui.class
pt/henrique/communityMarket/gui/ClaimGui$1.class
pt/henrique/communityMarket/model/ClaimItem.class pt/henrique/communityMarket/model/ClaimItem.class
pt/henrique/communityMarket/gui/ClaimGui$1.class
pt/henrique/communityMarket/util/ItemBuilder.class pt/henrique/communityMarket/util/ItemBuilder.class
pt/henrique/communityMarket/gui/NumberInputGui.class pt/henrique/communityMarket/gui/NumberInputGui.class
pt/henrique/communityMarket/gui/AdminGui.class pt/henrique/communityMarket/gui/AdminGui.class
pt/henrique/communityMarket/gui/ItemSelectionGui$SelectionMode.class
pt/henrique/communityMarket/gui/BrowseAuctionsGui.class pt/henrique/communityMarket/gui/BrowseAuctionsGui.class
pt/henrique/communityMarket/gui/ItemSelectionGui$SelectionMode.class
pt/henrique/communityMarket/service/TransactionService$TransactionResult.class pt/henrique/communityMarket/service/TransactionService$TransactionResult.class
pt/henrique/communityMarket/service/EarningsService.class pt/henrique/communityMarket/service/EarningsService.class
pt/henrique/communityMarket/service/TransactionService$ValidationResult.class pt/henrique/communityMarket/service/TransactionService$ValidationResult.class
@@ -56,8 +56,8 @@ pt/henrique/communityMarket/gui/GuiManager.class
pt/henrique/communityMarket/economy/EconomyManager$VaultAdapter.class pt/henrique/communityMarket/economy/EconomyManager$VaultAdapter.class
pt/henrique/communityMarket/gui/ClaimGui.class pt/henrique/communityMarket/gui/ClaimGui.class
pt/henrique/communityMarket/economy/EconomyManager$EssentialsAdapter.class pt/henrique/communityMarket/economy/EconomyManager$EssentialsAdapter.class
pt/henrique/communityMarket/gui/EarningsGui.class
pt/henrique/communityMarket/service/ListingService$PurchaseResult.class pt/henrique/communityMarket/service/ListingService$PurchaseResult.class
pt/henrique/communityMarket/gui/EarningsGui.class
pt/henrique/communityMarket/config/ConfigManager.class pt/henrique/communityMarket/config/ConfigManager.class
pt/henrique/communityMarket/gui/MarketGui$GuiType.class pt/henrique/communityMarket/gui/MarketGui$GuiType.class
pt/henrique/communityMarket/util/InventoryUtil$ItemCategory.class pt/henrique/communityMarket/util/InventoryUtil$ItemCategory.class
@@ -1,42 +1,42 @@
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/CommunityMarket.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/CommunityMarket.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/command/MarketCommand.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/command/MarketCommand.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/config/ConfigManager.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/config/ConfigManager.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/config/MessageManager.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/config/MessageManager.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/db/DatabaseManager.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/db/DatabaseManager.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/economy/EconomyManager.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/economy/EconomyManager.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/AdminGui.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/AdminGui.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/BrowseAuctionsGui.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/BrowseAuctionsGui.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/BrowseMarketGui.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/BrowseMarketGui.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/ClaimGui.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/ClaimGui.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/ConfirmationGui.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/ConfirmationGui.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/CreateAuctionGui.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/CreateAuctionGui.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/CreateListingGui.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/CreateListingGui.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/EarningsGui.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/EarningsGui.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/GuiManager.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/GuiManager.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/HelpGui.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/HelpGui.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/ItemSelectionGui.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/ItemSelectionGui.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/MainMenuGui.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/MainMenuGui.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/MarketGui.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/MarketGui.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/MyAuctionsGui.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/MyAuctionsGui.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/MyListingsGui.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/MyListingsGui.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/NumberInputGui.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/NumberInputGui.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/gui/QuantitySelectGui.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/gui/QuantitySelectGui.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/listener/GuiListener.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/listener/GuiListener.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/listener/PlayerListener.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/listener/PlayerListener.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/model/Auction.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/model/Auction.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/model/Bid.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/model/Bid.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/model/ClaimItem.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/model/ClaimItem.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/model/Listing.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/model/Listing.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/model/PendingEarnings.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/model/PendingEarnings.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/service/AuctionService.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/service/AuctionService.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/service/ClaimService.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/service/ClaimService.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/service/EarningsService.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/service/EarningsService.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/service/ListingService.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/service/ListingService.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/service/TransactionService.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/service/TransactionService.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/task/AuctionTask.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/task/AuctionTask.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/task/ExpiredListingTask.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/task/ExpiredListingTask.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/util/InventoryUtil.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/util/InventoryUtil.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/util/ItemBuilder.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/util/ItemBuilder.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/util/ItemSerializer.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/util/ItemSerializer.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/util/SoundUtil.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/util/SoundUtil.java
/Users/henrique/IdeaProjects/CommunityMarket/src/main/java/pt/henrique/communityMarket/util/TextUtil.java /root/mc-plugins-audit/repos/communitymarket/src/main/java/pt/henrique/communityMarket/util/TextUtil.java
Binary file not shown.