Список изменений
- Fixed Critical cross-server duplication where a sold item reappeared in the seller's items (multi-server / Redis). When
purchased-item.give-item: true, a purchase set the database row toDELETEDbefore broadcasting theItemBoughtevent; on every other server theItemBoughtListenerre-fetched the item viaselectItem(which filters outDELETEDrows), gotnull, and bailed out before removing the listing from its in-memory store. The ghost listing therefore survived on all non-buyer servers and the seller still saw it in/ah selling. The listener now removes the listing from in-memory storage unconditionally (mirroringItemRemovedListener), independently of the database lookup.ItemBoughtMessagewas enriched with the seller UUID/name, item display, price and buyer name so the real-time seller notification (including%buyer%, which was already broken on remote servers) works without a database round-trip - Fixed Purchased items not appearing on other servers with
purchased-item.give-item: false(multi-server / Redis). TheItemBoughtListenerremoved the item fromLISTEDon remote servers but never added it to their in-memoryPURCHASEDstore, so a buyer switching servers could not see their purchase until a restart. Remote servers now re-add the item toPURCHASED(the buyer-server purchase already did this locally; the buyer-server ignores its own message). Forgive-item: truethe message flagsgivenToBuyerso remote servers skip the (always-null) database lookup entirely - Fixed A crashed/timed-out purchase could leave an item permanently un-buyable in multi-server (Redis) setups. The lock key
auction:lock:<id>expires via TTL but the item hash fieldstate=LOCKEDpersisted (up to the item TTL, ~30 days), socheckAvailabilityreported the item as locked forever. Lock state now keys on the lock key's existence: aLOCKEDstate with no live lock key is treated as a stale lock and recovered. To prevent this recovery from ever enabling a double-purchase,PurchaseServicenow re-validates authoritative database state under the lock before charging — a row that is alreadyDELETEDor has a buyer aborts the purchase with nothing withdrawn - Fixed Expiration is now cluster-aware in multi-server (Redis) setups. Previously
ExpireServicemoved itemsLISTED -> EXPIREDpurely locally with no cluster coordination, so a lingering ghost of an item sold on another server could be resurrected as anEXPIREDitem for the seller (and claimed back = duplication). In distributed setups theLISTED -> EXPIREDtransition now locks the item, re-reads authoritative database state (skipping items sold elsewhere), performs the move, and broadcasts it so all nodes converge. Single-server setups keep the original fast path - Fixed
ItemRepositorycould overwrite a sold/removed item when expiring. TheLISTED -> EXPIREDupdate is now guarded withWHERE storage_type = 'LISTED', so an expirationUPDATEcan never clobber a row another server already set toDELETED/PURCHASED - Added DonutAuction migration - migrate data from the DonutAuction plugin (by EliVB) to zAuctionHouse V4 using
/ah admin migrate donutauction confirm(aliasesdonut,donutsmp,da). Readsplugins/DonutAuction/ah.datadirectly, so no database configuration is needed; active auctions are imported as listed items and past-expiry auctions as reclaimable expired items, while unclaimed pending payments (money, not items) are skipped. Legacy Base64 itemstacks are deserialized through a hardened class allowlist to guard against malicious data files - Fixed Cross-server purchases could fail with
IllegalArgumentException: name cannot be null(multi-server / Redis). When a buyer bought an item whose seller had never logged into that specific backend node,getSellerName()returnednulland was passed straight to the economy provider'swithdraw()call (and to the%seller%placeholder in the purchase notifications), aborting the purchase. The seller name is now resolved from the shared database before the economy call, falling back to the seller's UUID string (with a console warning to verify all servers share the same MySQL database) when even that lookup fails, so anullname can never reach downstream code - Fixed Purchases failing or charging incorrectly under CAPITALISM (VAT-style) tax - the balance check before buying only verified the buyer could afford the listed price, not the price plus the CAPITALISM tax added on top, so a player holding exactly the listed amount passed the check and the tax-inclusive withdrawal could then fail.
PurchaseServiceand theZAUCTIONHOUSE_LISTED_ITEMSbutton now check the tax-inclusive required balance when CAPITALISM tax is enabled - Fixed Items getting stuck in the "being purchased" state after a purchase failed for insufficient funds - the item was marked
IS_BEING_PURCHASEDbefore the funds check but only unlocked (not status-restored) on failure, so in multi-server (Redis) setups it stayed stuck and could no longer be bought. The status is now restored and broadcast to the cluster before unlocking - Fixed Money loss on economy errors during a purchase or claim - buyer withdraw, seller deposit and claim deposits are now wrapped in error handling: if the buyer is charged but the seller deposit throws, the buyer is automatically refunded; failed claim deposits are logged and skipped instead of silently losing the money
- Fixed Expired listings could still be displayed and counted in the auction house. Because expiration is processed lazily, an item could remain
AVAILABLEpast its expiry (especially while a cache was stale) and keep showing in the main list, in the per-category counts, and in the%zauctionhouse_listed_items%placeholder. A singleItem.isActivelyListed()predicate (available and not expired) is now applied at every display chokepoint, and interacting with a listing that has already expired now moves it to the player's expired items instead of opening a confirm inventory or re-showing it - Fixed The selling, expired, purchased, listed and combined item-list buttons ignored their inventory's
player-inventorysetting - paginated items and the empty-slot placeholder were always rendered into the chest GUI even when the inventory was configured as a player inventory. These buttons now render items into the player's own inventory area when configured (PR #25) - Fixed Auction search button always showed a hardcoded English
Nonein%search_query%when no search was active, ignoring the server language. TheZAUCTIONHOUSE_SEARCHbutton now reads a configurablenone-valueoption on the search button ininventories/auction.yml, with a localized default per language (None/Aucune/Ninguna/Nessuna/ไม่มี), so the empty-search text is translatable and customizable - Added Configurable
%search_active%value on the auction search button - theZAUCTIONHOUSE_SEARCHbutton now readsactive-value(defaulttrue) andinactive-value(defaultfalse) options ininventories/auction.yml, so the value returned by%search_active%when a search is / isn't active can be customized (e.g.Enabled/Disabled,Yes/No) instead of the hardcodedtrue/false - Changed Updated the required zMenu API to
1.1.1.6- make sure your server runs zMenu1.1.1.6or newer
Файлы
zAuctionHouse-4.0.1.0.jar(1.62 MiB)
ОсновнойМетаданные
Канал релиза
Release
Номер версии
4.0.1.0
Загрузчики
BukkitFoliaPaperPurpurSpigot
Версии игры
1.20–26.2
Загрузок
1.3K
Дата публикации
31.07.2026

