COWMODSКаталог модов

SoulAuction

One auction house for the whole network: multiple storefronts, any economy, Folia, and trade protection.

Автор: b0b0b0620обновлён 1 авг. 2026 г.
ПриключенияЭкономикаХранение

Описание

SoulAuction

One auction house for the whole network: multiple storefronts, any economy, Folia, and trade protection — no fat-jar, no click dupes.

SoulAuction is an auction plugin for Paper 1.21+ and Folia, built for when economy logic must survive region threading and double-purchase on a proxy is unacceptable.

Single JAR: dependencies via Paper libraries, no shade. Fewer conflicts with other plugins and easier updates.

Why admins choose it

Multiple auction houses in one plugin — regular, VIP, event, donation-currency, and more. Each has its own economy (Vault, PlayerPoints, experience, CoinsEngine, items), permissions, and rules. Not three separate AH plugins and not a sync zoo.

Folia first-class — region-aware threading, no legacy scheduler on hot paths. For networks already on Folia or migrating, this is baseline, not a nice extra.

Multi-server — shared MySQL + Redis: one catalog across the network, distributed locks for buy/sell, atomic listing state transitions in the database. Pub/sub refreshes the storefront; SQL is the source of truth, not “whoever wrote the file last”.

Players get a proper AH: GUI, categories, sorting, search and filters, favorite sellers, hub for “my listings / claim / history”. Messages use MiniMessage, HEX, gradients; texts live in lang/messages_*.yml.

Economy under control: seller and buyer taxes, bypass/discount via permissions, slot limits by rank, cooldowns, blacklist, world bans, item whitelist/blacklist, rules for ItemsAdder / Oraxen / MMOItems. Listing TTL; if inventory is full, items go to claim, not the void.

Operations: deal history, audit log, admin GUI, purge, claim recovery, Discord/Telegram deal notifications (async HTTP, no bot on the Minecraft server). /ah reload reloads config and messages.

Built for: Paper/Folia networks with multiple game modes and currencies, a shared auction across proxies, where anti-dupe matters more than “one more GUI button”.

Network and anti-dupe (short)

ModePurpose
JSON / YAMLsingle server, quick start
SQLITE / MYSQLpersistence; MYSQL is the proxy foundation
Redis + pub/subcross-instance locks + catalog cache invalidation

On a proxy: MYSQL + redis.enabled. Buy/cancel/expiry go through listing claim (lock + Redis NX + UPDATE … WHERE status='ACTIVE'), rollback on payment failure or full inventory. Sell: item held in escrow in GUI; inventory listing uses strict removal before DB write (/ah sell, no clone-without-consume).

Features

  • Multi-auction support, separate open / buy / sell permissions.
  • Currencies: VAULT, PLAYER_POINTS, EXPERIENCE, COINS_ENGINE, ITEM.
  • Storage: JSON, YAML, SQLITE, MYSQL.
  • Listing TTL (timed or unlimited), claim, seller notification on expiry, per-auction fees, sold/cancelled/expired history.
  • Listing limits: soulauction.<auctionId>.<N>, soulauction.all.<N>.
  • Sort priority: soulauction.priority.<N>.
  • Large-sale broadcast, external notifications (Discord/Telegram).
  • Sell GUI: amount ±1, pull matching items from inventory (up to max stack); comparison by full serialization (NBT, name, enchants), not “similar” stacks. Escrow until confirm — returned on cancel/close.
  • Per-auction price display: custom currency symbol, before/after number, MiniMessage and optional PlaceholderAPI in the symbol (resource pack / ItemsAdder icons, etc.).
  • Fake activity: synthetic listings from a nick/item pool, enabled per auction; timer refill, manual /ah admin fake, toggle in admin GUI.
  • Seller skins: heads in “Favorite sellers” via SkinsRestorer / Mojang; fallback and one shared skin for all fake sellers (server logo).

Price display (auctions/*.yml)

Each auction has its own fields (defaults in Java; after first start — plugins/SoulAuction/auctions/global.yml and others):

FieldPurpose
currencySymbolSymbol or icon in GUI and chat. Empty — economy default (Vault $, PlayerPoints PP, items Nx MATERIAL).
currencySymbolPositionBEFORE or AFTER the amount ($100 or 100 ₽).
currencySymbolPlaceholderApitrue — resolve %...% from PlaceholderAPI for the viewer (requires PlaceholderAPI).
listingTtlSecondsListing lifetime in seconds; 0 or less — no expiry.

Listing TTL and claim

  • While a listing is ACTIVE, the browser and “My listings” (if TTL enabled) show time left / expires at in lore; the open browser refreshes the timer every second.
  • Expired, unsold: listing removed (EXPIRED), item goes to claim once (claims.json), not the void.
  • Seller: chat message (online immediately, offline on join) with expiry notice and [Claim in menu] → /ah expired [auctionId]; item pickup — /ah claim (expired menu is view-only, slots are not editable).
  • Listing success: multi-line chat — item, amount, price, auction; separate block for timed or unlimited expiry (success-listed, success-listed-expiry-timed / success-listed-expiry-unlimited in lang/messages_*.yml).
  • Single process: lock on listingId + on SQL, ACTIVE → EXPIRED/SOLD/CANCELLED is atomic; claim is removed from buffer before inventory delivery.

currencySymbol examples:

  • Text: ₽, coins, gems
  • MiniMessage / glyph: <glyph:coin> (ItemsAdder, Nexo, etc. — per pack docs)
  • PAPI (with currencySymbolPlaceholderApi: true): %img_economy%

Custom symbol prices appear everywhere: GUI listings, sell menu, price filter, purchase, history, chat (success-bought, announce, etc.).

Messages (plugins/SoulAuction/lang/)

  • prefix — prefix for all {prefix} strings.
  • Keys use MiniMessage; {price} is already formatted for the auction the player is viewing.
  • Multi-line chat: key as a YAML list of strings — plugin sends each line separately (MessageService.send). Single string — as before. Chat search, sell success, expiry, command usage — in this format.
  • Listing lore placeholders in GUI: {seller}, {price}, {id}, {auction}, {expires_in}, {expires_at} (last two when TTL enabled); optional listingLoreTemplate in auctions/*.yml.

PlaceholderAPI

Expansion registers automatically when PlaceholderAPI is present. Identifier — soulauction, i.e. %soulauction_<param>%. Numbers are formatted for the player's locale (thousands separators). Any placeholder also has a _raw suffix variant — unformatted value (1500000 instead of 1,500,000, enum key instead of lang name) for scoreboards and plugins that need raw numbers.

Counters

PlaceholderValue
%soulauction_active_count%Player's active listings (aliases: sell_count, purchasable_count)
%soulauction_expired_count%Player's expired items (claims with reason EXPIRED)
%soulauction_total_active_count%All listings on the auction house
%soulauction_sell_limit%Player's global listing limit (permissions + override)
%soulauction_claims%All player items in claim
%soulauction_listings_all% / %soulauction_listings_<auctionId>%Player's active listings (all / specific auction)
%soulauction_listings_total%All listings (unformatted, legacy)

Player settings

PlaceholderValue
%soulauction_selected_sorting%Selected sort order
%soulauction_selected_category%Selected category
%soulauction_selected_currency%Currency of the last opened auction (currency-* from lang)
%soulauction_categories_enabled%, %soulauction_expired_items_enabled%, %soulauction_auction_listing_confirmation_enabled%Always true — these systems cannot be disabled in SoulAuction

Deal statistics

Persistent (data/stats.json); seeded once from existing history on first run. <currency> is economy type: vault, player_points, experience, coins_engine, item.

PlaceholderValue
%soulauction_items_sold%Items sold by the player
%soulauction_items_purchased%Items purchased by the player
%soulauction_money_made%Money earned by the player (after tax)
%soulauction_money_spent%Money spent by the player (with buyer tax)
%soulauction_items_sold_<currency>% and similarSame, per currency
%soulauction_total_items_sold%, %soulauction_total_money_made%, etc.Server-wide, including _<currency>

Fake activity

Synthetic listings keep the storefront busy: random nick from the pool, random item, random price in range. These are not real players — purchases work like normal listings (money is consumed, item is delivered). After a fake listing is bought, the plugin may list another one after a delay.

Per-auction enable

There is no global on/off in config.yml — only per auction:

WhereField / action
auctions/<id>.ymlfake-activity-enabled: true / false (default false)
/ah admin → right-click an auctionfake-activity menu
Menu → slot 22toggle (LIME_DYE / RED_DYE) → auctions/<id>.yml
Menu → slot 49pool, limits, tick (read-only)

Example in auctions/global.yml:

fake-activity-enabled: true

Pool (plugins/SoulAuction/fake-activity/)

Path: config.yml → fake-activity.directory (default fake-activity). On first start three files are created:

FileContents
settings.ymltimers, limits, default prices, admin-fake
sellers.ymlseller display names (max 16 chars)
items.ymlitem pool with weights and price ranges

Fresh install ships ~120 nicks and ~120 vanilla items (ores, food, tools, 1.21 rares) — edit in YAML anytime.

settings.yml (main fields)

FieldPurpose
initial-fill-listingslistings to create on startup (0 = up to max-total-listings)
initial-delay-secondsdelay before the first refill tick
tick-interval-secondshow often to top up toward limits
after-purchase-delay-secondsdelay after a fake buy before the same seller lists again
min-price / max-pricedefault range when an item in items.yml has min/max = 0
price-variance-percentrandom ±% on the chosen price
max-listings-per-auctionfake cap per auctionId
max-total-listingsfake cap server-wide
listing-age-spread-secondsrandom listing age on create (varied TTL timers)
listings-per-ticklistings to attempt per tick
auction-idsonly these auctions ([] = all with fake-activity-enabled)
admin-fake.register-sellerafter /ah admin fake, append nick to sellers.yml
admin-fake.register-itemafter /ah admin fake, append hand item to items.yml

items.yml entry fields

  • id — label for yourself
  • material / amount — vanilla stack (ignored when item-base64 is set)
  • item-base64 — full item snapshot (NBT, custom items)
  • min-price / max-price — 0 = from settings.yml
  • auction-ids — empty = any auction; otherwise only listed ids
  • weight — relative pick chance (higher = more often)

Manual fake listing

/ah admin fake <nick> <auctionId> <price>

Item must be in the main hand. Listing is created as synthetic immediately. With admin-fake.* enabled, nick and/or item are appended to the pool async.

Behaviour

  • Fakes appear in sorting, search, and filters like normal listings.
  • Only an admin with soulauction.command.cancel.any can /ah cancel them (seller is a synthetic UUID).
  • On a proxy with MySQL+Redis, fakes sync like any other listing.

Seller skins (config.yml → seller-skins)

Textures for seller heads in the “Favorite sellers” GUI (hub → star). Browser listings show the item itself, not a head.

SkinsRestorer is a soft dependency; on offline/cracked servers Mojang lookup by nick often fails without it.

source

ValueBehaviour
autoSkinsRestorer when installed; otherwise Mojang API
skins-restorerSkinsRestorer only
mojangMojang only (online-mode, real nicks)
offdefault Steve/Alex heads, no lookup

fallback-skin and fake-seller-skin

seller-skins:
  source: skins-restorer
  fallback-skin: "DefaultHead"
  fake-seller-skin: "ServerLogo"
FieldWhen
fallback-skinseller nick lookup failed → SR resolves this custom skin / nick / URL
fake-seller-skinall synthetic/fake sellers use this skin; nick is ignored

Values are SkinsRestorer skin names (/sr set skin ServerLogo <url>, etc.).

Lookup chain (SkinsRestorer)

  1. findOrCreateSkinData(nick) — or fake-seller-skin when the seller is synthetic and the field is set
  2. findSkinData(fallback-skin) — when configured
  3. getSkinForPlayer(uuid, nick) — SR defaultSkins from SkinsRestorer config

With source: mojang, fallback uses the Mojang API by name.

Startup warmup

Async prefetch into SkinsRestorer cache (~100 ms pause between requests):

  • if fake-seller-skin is set — warmup that skin (+ fallback-skin when set);
  • otherwise — all fake pool nicks + fallback-skin.

Console: SkinsRestorer — prefetched X/Y fake seller skins.

GUI lookup is async; the head updates when the texture arrives (no in-memory cache in SoulAuction).

Admin GUI

/ah admin or /ah admin gui [page] — requires soulauction.command.admin or OP.

ActionResult
Left-click an auctionopen storefront as a player
Right-click an auctionfake-activity menu
Slot 22toggle fake activity (wool)
Slot 49pool, limits, tick (read-only)
Slot 45back to auction list
Book in the bottom rowcreate a new auction (chat wizard)

Commands

Players

  • /ah — open the default auction.
  • /ah <auctionId> — open a specific auction.
  • /ah sell <price> — list the item in hand on the default auction.
  • /ah sell <auctionId> <price> — list on the chosen auction.
  • /ah sell <price> <auctionId> — alternative argument order.
  • /ah my [auctionId] — show your active listings.
  • /ah selling [auctionId] — active listings GUI.
  • /ah expired [auctionId] — expired items GUI (claim).
  • /ah purchased [auctionId] — purchase history GUI.
  • /ah history [auctionId] — sales history GUI.
  • /ah search <text> — search: closes GUI, prompt in chat (cancel button in message); after input — refreshed browser and result in chat.
  • /ah search <auctionId> <text> — same for a specific auction.
  • /ah search cancel — cancel search and return to the auction.
  • /ah page <number> [auctionId] — open a specific auction page.
  • /ah claim [all] — claim expired/cancelled items.
  • /ah cancel <id> — remove your listing and return the item.
  • Command aliases are configured in config.yml via commandAliases (e.g. ax, auction).

Admins

  • /ah reload — reload configs and messages.
  • /ah purge <days> — purge deal history older than N days.
  • /ah admin history <player> [limit] — player history in chat.
  • /ah admin selling <player> [auctionId] — player's active listings GUI.
  • /ah admin blacklist add|remove <player> — runtime sell blacklist.
  • /ah admin recover <claimId> — deliver claim to inventory.
  • /ah admin audit [limit] — recent audit entries.
  • /ah admin cache stats|rebuild|invalidate — catalog cache.
  • /ah admin sellfor <player> <auctionId> <price> — list on behalf of a player (item in hand).
  • /ah admin fake <nick> <auctionId> <price> — synthetic listing under the given nick (item in hand; see fake activity).
  • /ah admin gui [page] — auction list GUI (right-click an auction for fake activity).
  • /ah admin parse tags|nbt — parse NBT/tags of item in hand (custom items).
  • /ah view <player> [auctionId] — player's listings GUI.

Permissions

Basic

  • soulauction.command.ah — use /ah.
  • soulauction.command.sell — use /ah sell.
  • soulauction.command.reload — use /ah reload.
  • soulauction.command.admin — admin commands and purge.
  • soulauction.priority.10 — higher listing sort priority (any N).
  • soulauction.command.my — use /ah my.
  • soulauction.command.claim — use /ah claim.
  • soulauction.command.cancel.any — remove others' listings via /ah cancel.

Per-auction (set in config.yml)

Each auction has separate nodes:

  • openPermission — open this auction.
  • buyPermission — buy listings in this auction.
  • sellPermission — sell in this auction.

Example:

  • soulauction.open.vip
  • soulauction.buy.vip
  • soulauction.sell.vip

Dynamic listing limits

  • soulauction.<auctionId>.1 — limit 1 active listing in this auction.
  • soulauction.<auctionId>.5 — limit 5 active listings in this auction.
  • soulauction.all.1 — global limit 1 across all auctions.
  • soulauction.all.5 — global limit 5 across all auctions.

If multiple nodes are granted, the highest limit applies. If none are granted, defaults from limits are used.

Taxes

  • soulauction.tax.bypass — no sale or purchase tax.
  • soulauction.tax.discount.<percent> — sale tax discount (highest wins).

In auctions/*.yml: saleTaxPercent (from seller), buyTaxPercent (from buyer).

Price bounds

  • Global: limits.minPrice, limits.maxPrice in config.yml.
  • Per-auction: minPrice, maxPrice (0 = use global).
  • soulauction.price.min.<price> — minimum listing price for a player.
  • soulauction.price.max.<price> — maximum listing price for a player.

Discord and Telegram

In config.yml → notifications section:

  • Discord: notifications.discord.enabled, webhookUrl (channel Incoming Webhook).
  • Telegram: notifications.telegram.enabled, botToken, chatId.
  • Events: notify-sold, notify-listed, notify-expired, min-price filter.
  • Delivery is async (Java HTTP), no shade, no bot on the Minecraft server.
  • Player avatars in Discord: notifications.discord.show-player-avatars (seller head in author, buyer thumbnail on deals). CDN: avatar-provider = MINOTAR (default) or CRAFATAR.

After /ah reload, new URLs and flags are picked up.

Галерея

Последние версии

Все версии →
release

SoulAuction 1.2.2

1.2.2
1 авг. 2026 г.46Minecraft: 1.21, 1.21.1, 1.21.2, 1.21.3, 1.21.4, 1.21.5, 1.21.6, 1.21.7, 1.21.8, 1.21.9, 1.21.10, 1.21.11, 26.1, 26.1.1, 26.1.2, 26.2, 26.3folia, paper, purpur
Скачать
Что нового
- Added fake sellers (auto-sellers) - Added command tab completion
release

SoulAuction 1.2.1

1.2.1
1 авг. 2026 г.6Minecraft: 1.21, 1.21.1, 1.21.2, 1.21.3, 1.21.4, 1.21.5, 1.21.6, 1.21.7, 1.21.8, 1.21.9, 1.21.10, 1.21.11, 26.1, 26.1.1, 26.1.2, 26.2folia, paper, purpur
Скачать
Что нового
- Added bStats metrics - Minor versioning refactor - Log cleanup
release

SoulAuction 1.2

1.2
31 июл. 2026 г.10Minecraft: 1.21, 1.21.1, 1.21.2, 1.21.3, 1.21.4, 1.21.5, 1.21.6, 1.21.7, 1.21.8, 1.21.9, 1.21.10, 1.21.11, 26.1, 26.1.1, 26.1.2, 26.2folia, paper, purpur
Скачать
Что нового
- Auto-connect to available economy plugins (Vault, PlayerPoints, CoinsEngine)