Аукцион
Игроки выставляют предметы из руки, покупают через GUI и забирают непроданное из /ah expired.
Команды 1#
Как устроен аукцион#
Отдельный модуль форка: игроки выставляют весь стек из основной руки командой /ah sell <цена>, остальные покупают через GUI /ah. Непроданное после таймера уходит в /ah expired и ждёт, пока продавец заберёт.
Денежный контур — тот же Vault/EconomyAPI, что у /pay. Конфиг — config/auctionhouse.json (не папка neoessentials/). Данные — коллекции DataStore auction_listings / auction_expired.
Модуль выключается modules (auction house) и commands.ah. Пока команда выключена, Brigadier-дерево не регистрируется.
Примеры#
Выставить предмет и купить его с другого аккаунта#
Проверить, что экономика и GUI связаны: продавец теряет предмет из руки, покупатель платит, продавец получает деньги даже офлайн.
/ah sell 250
/ah selling
/ah
sell забирает весь стек из основной руки (пустая рука — «need_item», цена ≤ 0 не пройдёт уже на уровне Brigadier). В /ah selling лот виден у продавца с таймером; в /ah — у всех. Покупка идёт кликом в GUI, не командой. Если у игрока уже maxItemsPerPlayer активных лотов, sell ответит ошибкой про лимит и предмет останется в руке.
Забрать непроданное после истечения#
Лот висел неделю (auctionSecondsDuration, по умолчанию 604800 с) и пропал из витрины — его нельзя потерять молча.
/ah expired
Открывается GUI непроданного. Забрать можно только свои лоты. Предмет возвращается в инвентарь или падает под ноги, если места нет. Пока игрок не забрал — запись живёт в коллекции auction_expired того же storage.type, что и весь мод.
Перечитать лимит лотов без рестарта#
Поменяли maxItemsPerPlayer в config/auctionhouse.json и хотите, чтобы новый потолок начал действовать сразу.
/ah reload
Перечитывается только config/auctionhouse.json (не config.json и не crates.json). Нужен neoessentials.ah.reload (или OP при opsBypassPermissions). Уже выставленные лоты не обрезаются — лимит проверяется только при новом /ah sell.
Тонкие места#
Конфиг лежит не в config/neoessentials/#
AuctionConfig пишет config/auctionhouse.json в корне конфигов сервера, а не в config/neoessentials/. В нём три ключа: maxItemsPerPlayer (10), auctionSecondsDuration (604800), maxPages (50). /neoe reload этот файл не трогает.
Что делать: Правите config/auctionhouse.json и делайте /ah reload. Модуль целиком включается modules + commands.ah — после их смены нужен рестарт.
Двойной клик в двух GUI больше не дублирует предмет#
cancelListing и buyItem сначала атомарно снимают лот с activeListings, и только потом двигают предметы и деньги. Раньше два окна на один лот давали два предмета или двойную оплату. Если снять не удалось — метод возвращает false и ничего не меняет. Если у покупателя не хватает денег, лот возвращают в список.
Что делать: Если игрок клянётся, что «купил, а предмета нет» — смотрите logs/debug.log с категорией auctionHouse.debug, а не полагайтесь на чат: GUI может закрыться раньше сообщения.
Продавца оплачивают даже если deposit отменили#
После успешного withdraw с покупателя листинг уже снят. EconomyAPI.deposit продавцу может отменить слушатель EconomyDepositEvent или упереться в потолок баланса. Тогда менеджер ставит баланс через setBalance, минуя отменяемое событие — иначе деньги покупателя исчезали бы в никуда.
Что делать: Не рассчитывайте, что плагин защиты экономики заблокирует оплату с аукциона. Потолок баланса продавца при этом можно превысить.
Общий DataStore, не свой auctionhouse.db#
Активные лоты — коллекция auction_listings, истёкшие — auction_expired, бэкенд тот же, что storage.type. Старый auctionhouse.db импортируется один раз, если коллекция пустая и autoMigrate включён. Числовой id лота сохраняется при переносе в expired.
Что делать: После смены storage.type не копируйте auctionhouse.db руками — дождитесь миграции или проверьте neoessentials/store/.
Права 3#