Вы используете устаревший браузер. Этот и другие сайты могут отображаться в нем неправильно. Необходимо обновить браузер или попробовать использовать другой.
Добавлено: интеграция метрик FastStats в дополнение к уже используемому bStats. Клиент FastStats включён в итоговый JAR и перемещён в отдельный пакет, запускается после инициализации плагина и корректно завершается вместе с ним.
Исправлено: в итоговом JAR находились три дубликата META-INF/faststats.properties. FastStats теперь находится только в корневом модуле плагина, а Shadow сохраняет единственную копию идентичной информации о версии.
Добавлено: индонезийская локализация (id) с переводом конфигурации, сообщений, правил, категорий, настроек Discord, инвентарей и паттернов. Автоматическое определение языка теперь выбирает индонезийский для серверов, расположенных в Индонезии.
Исправлено: инвентари администратора для просроченных, купленных и выставленных на продажу предметов не отображали настроенный в YAML предмет для пустого состояния, если у выбранного игрока не было подходящих предметов.
Обновлено: зависимость CurrenciesAPI обновлена с версии 1.0.13 до 1.0.14. Неправильно написанный тип экономики EXCELLENTEECONOMY переименован в EXCELLENTECONOMY. Теперь оба варианта принимаются в качестве типа в economies.yml; старый вариант помечен как устаревший и будет удалён в одном из будущих обновлений CurrenciesAPI.
Добавлено:права для кнопок администратора:
admin_expired_items_remove — позволяет удалять просроченные предметы с аукциона.
admin_logs_give_item_to_player — позволяет выдавать предметы другим игрокам из логов аукциона.
admin_purchased_items_remove — позволяет удалять купленные предметы с аукциона.
admin_listed_items_remov — позволяет удалять выставленные предметы с аукциона.
Добавлена настройка allow-decimal-prices в config.yml (по умолчанию true). При значении false игроки больше не смогут выставлять предметы на продажу по цене с десятичными значениями (например, 10.5). Разрешены только целые числа.
Проверка применяется ко всем способам продажи через SellService:
команда /ah sell;
кнопка подтверждения продажи в меню инвентаря.
Добавлено новое сообщение price-decimal-not-allowed, которое отображается при попытке указать дробную цену.
Настройка и сообщение синхронизированы во всех языковых файлах (en/fr/es/it/th).
Исправлено Критическое дублирование между серверами, при котором проданный предмет снова появлялся у продавца (мультисервер / Redis). Когда purchased-item.give-item: true, после покупки строка предмета в базе данных переводилась в DELETED до отправки события ItemBought; на всех остальных серверах ItemBoughtListener заново получал предмет через selectItem (который исключает строки DELETED), получал null и прекращал выполнение до удаления объявления из своего хранилища в памяти. Из-за этого призрачное объявление оставалось на всех серверах, кроме сервера покупателя, и продавец всё ещё видел его в /ah selling. Теперь слушатель безусловно удаляет объявление из хранилища в памяти (как ItemRemovedListener), независимо от результата запроса к базе данных. ItemBoughtMessage дополнен UUID/именем продавца, отображением предмета, ценой и именем покупателя, поэтому уведомление продавца в реальном времени (включая %buyer%, которое уже не работало на удалённых серверах) теперь работает без дополнительного обращения к базе данных
Исправлено Отсутствие купленных предметов на других серверах при purchased-item.give-item: false (мультисервер / Redis). ItemBoughtListener удалял предмет из LISTED на удалённых серверах, но никогда не добавлял его в их хранилище PURCHASED в памяти, поэтому при переходе покупателя на другой сервер покупка была недоступна до перезапуска. Теперь удалённые серверы повторно добавляют предмет в PURCHASED (сервер покупателя уже делал это локально; он игнорирует собственное сообщение). Для give-item: true сообщение теперь содержит флаг givenToBuyer, поэтому удалённые серверы полностью пропускают бесполезный (всегда null) запрос к базе данных
Исправлено Сломанная/прерванная покупка могла оставить предмет навсегда недоступным для покупки в мультисерверных (Redis) конфигурациях. Ключ блокировки auction:lock:<id> удаляется через TTL, но поле состояния предмета state=LOCKED в хэше Redis оставалось (до TTL предмета, примерно 30 дней), поэтому checkAvailability считал предмет заблокированным навсегда. Теперь состояние LOCKED зависит от существования ключа блокировки: если LOCKED установлен, но активного ключа блокировки нет — это считается устаревшей блокировкой и выполняется восстановление. Чтобы это восстановление никогда не приводило к двойной покупке, PurchaseService теперь повторно проверяет актуальное состояние базы данных под блокировкой перед списанием денег — если строка уже DELETED или у неё есть покупатель, покупка отменяется без списания средств
Исправлено Истечение срока действия теперь учитывает кластер в мультисерверных (Redis) конфигурациях. Ранее ExpireService переводил предметы LISTED -> EXPIRED только локально, без координации между серверами, поэтому оставшийся призрак предмета, который был продан на другом сервере, мог снова появиться как EXPIRED у продавца (и быть возвращённым обратно = дублирование). Теперь в распределённых конфигурациях переход LISTED -> EXPIRED блокирует предмет, повторно читает актуальное состояние из базы данных (пропуская предметы, проданные на другом сервере), выполняет перенос и отправляет обновление всем узлам, чтобы все серверы пришли к одному состоянию. Односерверные конфигурации продолжают использовать быстрый старый путь
Исправлено ItemRepository мог перезаписывать уже проданный/удалённый предмет при истечении срока действия. Обновление LISTED -> EXPIRED теперь защищено условием WHERE storage_type = 'LISTED', поэтому запрос на истечение срока больше никогда не сможет затереть строку, которую другой сервер уже перевёл в DELETED/PURCHASED
Добавлено Миграция DonutAuction — перенос данных из плагина DonutAuction (от EliVB) в zAuctionHouse V4 через команду /ah admin migrate donutauction confirm (алиасы donut, donutsmp, da). Данные напрямую читаются из plugins/DonutAuction/ah.data, поэтому настройка базы данных не требуется; активные аукционы импортируются как выставленные предметы, а завершённые аукционы с истёкшим сроком — как доступные для возврата предметы. Невостребованные ожидающие выплаты (деньги, не предметы) пропускаются. Старые Base64 itemstack'и проходят десериализацию через защищённый список разрешённых классов для защиты от вредоносных файлов данных
Исправлено Покупки между серверами могли завершаться ошибкой IllegalArgumentException: name cannot be null (мультисервер / Redis). Когда покупатель приобретал предмет, продавец которого никогда не заходил на конкретный серверный узел, getSellerName() возвращал null и напрямую передавался в withdraw() экономического провайдера (а также в плейсхолдер %seller% уведомлений о покупке), из-за чего покупка отменялась. Теперь имя продавца сначала берётся из общей базы данных, а если даже этот запрос неудачен — используется UUID продавца с предупреждением в консоли о необходимости проверить, что все серверы используют одну MySQL базу. Таким образом, null больше никогда не попадёт в последующий код
Исправлено Покупки могли ломаться или списывать неверную сумму при использовании налога CAPITALISM (налог в стиле НДС). Проверка баланса перед покупкой учитывала только цену предмета, но не цену с добавленным налогом CAPITALISM, поэтому игрок с балансом ровно равным цене проходил проверку, а списание с налогом позже могло завершиться ошибкой. Теперь PurchaseService и кнопка ZAUCTIONHOUSE_LISTED_ITEMS проверяют необходимый баланс с учётом налога, если включён CAPITALISM
Исправлено Предметы могли застревать в состоянии "покупается" после неудачной покупки из-за недостатка средств. Предмет переводился в IS_BEING_PURCHASED до проверки денег, но при ошибке только разблокировался без восстановления статуса, поэтому в мультисерверных (Redis) конфигурациях он оставался зависшим и больше не мог быть куплен. Теперь статус восстанавливается и отправляется в кластер до снятия блокировки
Исправлено Потеря денег при ошибках экономики во время покупки или возврата. Списание у покупателя, начисление продавцу и выплаты при возврате теперь обрабатываются через систему ошибок: если деньги у покупателя списались, но перевод продавцу завершился ошибкой — покупатель автоматически получает возврат. Ошибки выплат при возврате теперь записываются в лог и пропускаются вместо тихой потери денег
Исправлено Истёкшие объявления всё ещё могли отображаться и учитываться в аукционе. Так как обработка истечения срока выполняется лениво, предмет мог оставаться AVAILABLE после окончания срока (особенно при устаревшем кеше) и продолжал отображаться в основном списке, категориях и плейсхолдере %zauctionhouse_listed_items%. Теперь единая проверка Item.isActivelyListed() (доступен и не просрочен) применяется во всех местах отображения, а взаимодействие с уже просроченным объявлением теперь перемещает его в просроченные предметы игрока вместо открытия меню подтверждения или повторного отображения
Исправлено Кнопки списков продаваемых, просроченных, купленных, выставленных и объединённых предметов игнорировали настройку инвентаря player-inventory. Пагинация предметов и пустой слот всегда отображались в сундук GUI даже когда инвентарь был настроен как инвентарь игрока. Теперь эти кнопки отображают предметы в области собственного инвентаря игрока при соответствующей настройке (PR #25)
Исправлено Кнопка поиска аукциона всегда показывала жёстко заданное английское None в %search_query%, когда поиск не был активен, игнорируя язык сервера. Кнопка ZAUCTIONHOUSE_SEARCH теперь использует настраиваемое значение none-value из inventories/auction.yml, с локализованным значением по умолчанию для каждого языка (None / Aucune / Ninguna / Nessuna / ไม่มี), поэтому текст пустого поиска теперь можно переводить и изменять
Добавлено Настраиваемое значение %search_active% для кнопки поиска аукциона. Кнопка ZAUCTIONHOUSE_SEARCH теперь использует параметры active-value (по умолчанию true) и inactive-value (по умолчанию false) из inventories/auction.yml, поэтому значение %search_active% при активном/неактивном поиске можно изменять (например Enabled/Disabled, Yes/No) вместо фиксированных true/false
Изменено Обновлена требуемая версия API zMenu до 1.1.1.6 — убедитесь, что ваш сервер использует zMenu версии 1.1.1.6 или новее
Исправлен спам предупреждениями Item not found for log ID в истории продаж. Логи, перенесённые из V3, создавались с item_id = 0 (так как прямого соответствия предметам V4 нет), из-за чего для каждой записи выводилось предупреждение. Теперь такие записи отфильтровываются на уровне SQL.
Добавлены настройки истории в config.yml:
history.max-entries — ограничивает количество отображаемых записей истории на игрока (по умолчанию: 500, 0 — без ограничений).
history.expire-after-days — скрывает записи старше указанного количества дней (по умолчанию: 0 — не истекают).
Полезно для серверов с большим количеством транзакций, чтобы снизить нагрузку на базу данных и ускорить загрузку истории.
Добавлены команды управления логами для администраторов:
/ah admin logs purge <days> — удаляет все логи старше указанного количества дней.
/ah admin logs player <player> — удаляет все логи конкретного игрока.
/ah admin logs clear-migrated — удаляет все логи, перенесённые из V3 (item_id = 0).
Все операции выполняются асинхронно и сообщают количество удалённых записей.
Исправлены «призрачные» предметы в /ah selling на мультисерверных (Redis) сборках. Ранее, если игрок удалял предмет на сервере №1 и переходил на сервер №2, предмет мог оставаться в продаже с пометкой «покупается» и блокировать слот продажи. Внесены три исправления:
ItemRemovedListener теперь сразу удаляет предмет из памяти после получения сообщения, не дожидаясь асинхронного запроса к БД.
RemoveService больше не восстанавливает статус предмета через Redis, если локальное удаление уже завершилось.
getPlayerSellingItems теперь дополнительно отфильтровывает предметы со статусом DELETED.
Изменён плейсхолдер Discord webhook %expires_at%: теперь он использует динамическую метку времени Discord (<t:unix_seconds:f>) вместо заранее отформатированной даты. Discord автоматически покажет дату в локальном часовом поясе каждого пользователя. Для предметов без срока действия по-прежнему используется обычная дата.
Добавлена поддержка кастомных изображений предметов для Discord webhook:
В discord.yml появилась новая секция custom-images.
Можно переопределить %item_image_url% для конкретных предметов.
Поддерживаются правила в том же формате, что и categories.yml / rules.yml: material, name, lore, custom-model-data, oraxen, itemsadder, nexo, mmoitems и другие.
Используется первое совпавшее правило.
Если совпадений нет, применяется стандартное изображение по материалу предмета.
Цвет изображения теперь кэшируется по URL, поэтому разные кастомные предметы с одинаковым материалом больше не конфликтуют между собой.
Исправлена критическая ошибка дублирования предметов в мульти-серверных (Redis) сетапах: при удалении предмета из интерфейса продажи он корректно выдавался игроку и помечался как DELETED в базе данных, но другие серверы получали общее событие удаления (LISTED) и ошибочно восстанавливали предмет в кеше EXPIRED, что позволяло получить его повторно на другом сервере.
Исправлена проблема в ItemRepository.select(int id), из-за которой запрос по одному предмету не фильтровал записи со статусом DELETED, в то время как массовый select() корректно их исключал. Это приводило к повторной загрузке удалённых предметов через Redis ItemRemovedListener.
Добавлен параметр destinationStorageType в метод удаления cluster bridge: теперь ItemRemovedMessage передаёт точный тип назначения (DELETED или EXPIRED), чтобы другие серверы не определяли его «наугад». Обратная совместимость сохранена через дефолтный метод в AuctionClusterBridge.
Полностью переработан ItemRemovedListener (Redis addon) с усиленной защитой: теперь используется явный тип из сообщения, затем проверка состояния в базе данных, и больше не предполагается автоматическое восстановление в EXPIRED.
Исправлена ошибка миграции CreateOptionsMigration, вызывавшая сбой MySQL errno: 150 "Foreign key constraint is incorrectly formed" — колонка player_unique_id использовала тип uuid(), что могло создавать несовместимую коллацию (особенно на MySQL 8.0+). Изменено на string(36), чтобы совпадать с остальными внешними ключами, ссылающимися на players.unique_id.
Добавлена поддержка banned-rules для категорий — позволяет исключать конкретные предметы из категории даже если они соответствуют правилам включения (material, tag, lore, custom-model-data и т.д.). Например, нетеритовая мотыга обычно попадает в категорию Tools, но может быть исключена по CustomModelData (например, 300)
Добавлена система Broadcast — отправляет сообщения всем онлайн-игрокам при продаже или покупке предметов
Настраивается отдельно для sell/purchase
Можно исключать продавца/покупателя
Поддерживает переопределение сообщений по категориям (MiniMessage)
Добавлена кнопка ZAUCTIONHOUSE_COMBINED_ITEMS — объединяет продаваемые, просроченные и купленные предметы в единый интерфейс с пагинацией
Для каждого типа можно отдельно включать/отключать отображение через include-selling, include-expired и include-purchased
Действия по клику автоматически адаптируются под тип хранения предмета (отмена продажи, получение просроченного предмета, получение купленного предмета)
Для каждого типа предметов используется собственная настройка lore из config.yml
Исправлен дюп предметов в multi-server (Redis) сетапах — удаление лота на одном сервере и получение просроченного предмета могло оставлять «призрачную» запись на другом сервере, позволяя получить предмет повторно после естественного истечения
Исправлен ItemRemovedListener (Redis addon)
Удалена нестабильная проверка состояния БД, вызывавшая отклонение сообщений удаления из-за race condition
Добавлена дополнительная очистка для всех типов хранилищ
Исправлен ItemStatusListener (Redis addon)
Синхронизация статусов теперь ищет предметы во всех типах хранилищ (LISTED, EXPIRED, PURCHASED), а не только в LISTED
Исправлен ExpireService
Добавлена защита от повторного истечения предметов, уже удалённых/полученных на другом сервере
Добавлена поддержка Redis Sentinel (Redis addon)
Поддерживаются high-availability Redis-сетапы с автоматическим поиском master-ноды и failover
Используйте mode: "sentinel" в config.yml и укажите sentinel-ноды
Полностью обратно совместимо — существующие standalone-конфиги продолжат работать без изменений
Исправлен NullPointerException, если не настроена экономика по умолчанию
Команда /ah sell и все связанные кнопки теперь показывают ошибку вместо краша
Добавлена проверка при запуске с заметными предупреждениями в консоли, если default economy отсутствует в economies.yml
Исправлены неверные названия типов экономики в комментариях economies.yml
COINS_ENGINE и PLAYER_POINTS не соответствовали enum-значениям CurrenciesAPI (COINSENGINE, PLAYERPOINTS)
Из-за этого данные типы экономики не загружались, если использовались названия из документации
Добавлено
Все permissions теперь автоматически регистрируются в Spigot при запуске и reload
Включены статические permissions (use, sell, admin и т.д.) и динамические permissions из конфигов (лимиты лотов, уровни истечения, bypass/reduction налогов, доступ к экономикам, inventory-команды, bypass кулдаунов)
Все permissions сгруппированы под wildcard zauctionhouse.*
Исправлено выпадение предметов на землю при получении просроченных, купленных или продаваемых предметов с полным инвентарём
Теперь предметы остаются в хранилище, если инвентарь игрока заполнен
Добавлена настройка player-inventory-must-have-free-space в секциях remove-expired-item и selling-item (включена по умолчанию)
Добавлены кнопки:
ZAUCTIONHOUSE_REMOVE_ALL_EXPIRED
ZAUCTIONHOUSE_REMOVE_ALL_SELLING
ZAUCTIONHOUSE_REMOVE_ALL_PURCHASED
Позволяют забрать все предметы сразу из соответствующих разделов
Предметы выдаются по одному и процесс останавливается при заполнении инвентаря (если включён player-inventory-must-have-free-space)
Добавлен API ItemContentProvider
Система для отображения содержимого контейнеров (шалкеры, кастомные контейнеры других плагинов)
Сторонние плагины могут регистрировать собственные providers через: AuctionPlugin.getItemContentManager().registerProvider()
Добавлен hook для AxShulkers
Теперь содержимое шалкеров из AxShulkers отображается в просмотрщике содержимого предметов
Так как AxShulkers хранит данные вне vanilla NBT, этот hook обязателен для просмотра содержимого
Исправлено: продавец не получал деньги в multi-server (Redis) сетапах, если покупатель находился на другом сервере
Плагин пытался начислить деньги локально на сервере покупателя, где аккаунт продавца мог отсутствовать
Теперь деньги переводятся в статус PENDING и получаются продавцом через /ah claim или автоматически при входе
Добавлен AuctionClusterBridge.isDistributed()
Позволяет bridge-реализациям указывать, что используется multi-server окружение, чтобы плагин мог адаптировать поведение (например, откладывать выдачу денег вместо локального начисления)
Добавлена кнопка ZAUCTIONHOUSE_CLAIM — отображает ожидаемые средства по каждой экономике с динамическими placeholder’ами и позволяет игрокам забирать их прямо из GUI аукциона
Добавлен настраиваемый loading-item для кнопки получения, который отображается во время загрузки данных о средствах
Добавлен формат цены PRICE_WITHOUT_DECIMAL — отображает цену без десятичных знаков (например, 10000.50 → 10000)
Добавлен placeholder %price-price-without-decimal% — отображает цену без десятичных знаков в описании предмета
Добавлено: команду /ah admin forceopen теперь можно выполнять из консоли
Добавлена настройка часового пояса — позволяет изменить таймзону для всех placeholder’ов дат (%date%, %formatted-expire-date%, %expires_at%). Поддерживаются все ID Java TimeZone (например, Europe/Paris, America/New_York, UTC). По умолчанию auto (часовой пояс сервера)
Исправлено: автодополнение команд /ah admin open и /ah admin history больше не загружает всех офлайн-игроков, что предотвращает лаги на серверах с большим количеством игроков
Исправлен краш updateListedItems на Folia/Canvas — доступ к inventory holder выполнялся в асинхронном потоке вместо основного тика
Исправлена настройка аргумента имени экономики для команды продажи — если индекс аргумента экономики не был задан, значение по умолчанию игнорировалось, что приводило к null имени экономики
Добавлена миграция из ZelAuction — перенос данных из плагина ZelAuction в zAuctionHouse V4 с помощью команды /ah admin migrate zelauction confirm
Добавлена система поиска — игроки могут искать предметы по имени, материалу, описанию или продавцу прямо в GUI аукциона или через команду /ah search <query>
Добавлена кнопка ZAUCTIONHOUSE_SEARCH — открывает чат для ввода поиска с поддержкой расширенных фильтров
Добавлена кнопка ZAUCTIONHOUSE_CLEAR_SEARCH — очищает активный фильтр поиска, видна только при активном поиске
Добавлена команда /ah search <query> — поиск предметов напрямую из чата без открытия GUI
Добавлены расширенные фильтры поиска с операторами:
~ — содержит
= — точное совпадение
~= — содержит, без учёта регистра
== — точное совпадение, без учёта регистра
Поддерживаемые поля для поиска: имя, материал, описание, продавец (например, seller = Notch, name ~ Diamond)
Добавлена команда /ah admin forceopen <player> <inventory> [page] — открыть любой инвентарь игрока на определённой странице. Поддерживаются все имена инвентарей (например, auction, admin-selling-items, history, admin-logs и т.д.) с автозаполнением. Страница по умолчанию — 1
Добавлена опция конфигурации reset-search-on-open — при включении (по умолчанию: true) фильтр поиска очищается каждый раз при открытии аукциона, аналогично поведению reset-category-on-open