Repository navigation
Releases
UltiTrade 2.1.0
Added
-
Optional fixed lifetime for an open trade window:
window-timeoutinconfig/trade.yml(seconds,
0–600, shipped0= unlimited). Both players are told the duration when the windows open and warned
once in the last ten seconds; at expiry the trade is cancelled through the normal cancel path, so each
player's items come back (an unavailable player's are kept as a pending return) and no money or
experience moves. A reload applies the new value to newly opened trades only. The legacy
trade-timeoutkey stays ignored (#41). -
新增可选的交易窗口固定时限:
config/trade.yml中的window-timeout(秒,0–600,默认0不限时)。开窗时双方获知时长,
最后十秒提醒一次;到期按正常取消流程取消,各自物品退回(无法找到的玩家沿用待返还机制),金币与经验不变。
重载只影响之后新开的交易;旧键trade-timeout仍被忽略(#41)。 -
Optional
server-nameinconfig/trade.yml(shipped empty): the name this server writes into new
pending-return claims, shown in/trade pending listas<server-name>@<bind IP>:<port>. Empty keeps the
server folder's name as before; the value is trimmed and at most 64 characters are used. Useful when several
servers share one database and run from folders with the same name (#95). -
config/trade.yml新增可选的server-name(默认留空):本服写入新待返还占用记录的名称,在/trade pending list中显示为
<server-name>@<绑定 IP>:<端口>。留空则与以前一样使用服务器文件夹名;取值会去掉首尾空格,最多使用 64 个字符。适用于多台服务器共用一个
数据库且文件夹名相同的情况(#95)。 -
On Minecraft versions below 1.21, the module now refuses to enable on UltiTools older than 6.4.0 and
logs one error naming the server and UltiTools versions ("UltiTrade needs UltiTools 6.4.0 or later on
Minecraft versions below 1.21 …"); the UltiTools core plugin keeps running. On 1.21 and later nothing
changes, and UltiTools 6.3.0 or later is still enough. If either version cannot be read, the module logs
a warning and starts without the check (#93, UltiKits/UltiTools-Reborn#655). -
在 Minecraft 1.21 以下版本上,若 UltiTools 低于 6.4.0,本模块会拒绝启用,并记录一条写明服务器与 UltiTools 版本的错误
(「UltiTrade needs UltiTools 6.4.0 or later on Minecraft versions below 1.21 …」);UltiTools 核心插件照常运行。
1.21 及以上版本不受影响,仍只需 UltiTools 6.3.0 或更高版本。无法解析任一版本时记录一条警告,不做该检查直接启动
(#93、UltiKits/UltiTools-Reborn#655)。 -
The module JAR now carries MIT licence metadata and a
LICENSEfile (#91). -
模块新增 MIT 许可证元数据与
LICENSE文件(#91)。
Changed
- When a trade is cancelled while the partner is offline and their real last location cannot be read
(including servers without an offline-location API), the partner's stake now goes to the player who
started the trade. Before, it was always saved for the offline partner, and if that save failed it was
dropped at the first world's spawn. An online initiator receives it in the inventory (overflow drops at
their feet) and is told so; an offline initiator gets it saved as a pending return under their UUID,
delivered at their next join and kept across a normal restart. Items that do not fit at a join now stay
saved for a later join instead of dropping. If the offline owner's real location is known, their stake is
still saved for them, and a failed save drops it at that real location; the world spawn is no longer used
as a stand-in (#92, UltiKits/UltiTools-Reborn#655). - 交易取消时若对方离线且无法读取其真实离线位置(包括没有离线位置 API 的服务器),对方的押物改为返还给发起交易的玩家。
以前一律为离线方保存,保存失败时掉落在第一个世界的出生点。发起人在线时放入背包(放不下的掉在其脚下)并收到提示;
发起人离线时按其 UUID 存为待返还记录,下次进服时发还,正常停服重启不会丢失。进服时装不下的部分现在继续保存,等下次进服再领,
不再掉在地上。若能取得离线物主的真实位置,仍为其保存,保存失败时掉落在该真实位置;不再以世界出生点代替
(#92、UltiKits/UltiTools-Reborn#655)。 /trade block,/trade unblockand trade requests (including shift+right-click) now share one wait
allowance of about 50 ms across all their settings-lock attempts, instead of waiting up to 50 ms again at
each check (#68)./trade block、/trade unblock与交易请求(包括 Shift+右键)现在在全部设置锁尝试中共用约 50 毫秒的等待额度,
不再在每次检查时各等最多 50 毫秒(#68)。
Fixed
- Typing a fractional experience amount (such as
1.5) or one above 2,147,483,647 in the trade window's
chat prompt is now refused with "Invalid amount!" and leaves both offers and both confirmations unchanged,
also after experience trading has been disabled by a reload. A whole-number decimal such as1.0is
accepted (#67). - 在交易窗口的聊天输入中填写带小数的经验数量(如
1.5)或超过 2,147,483,647 的数量,现在会以「Invalid amount!」拒绝,
双方报价与确认状态均不改变,经验交易被重载关闭后同样如此。1.0这类整数值的小数写法仍可接受(#67)。 - The console warning for a saved trade stake that an operator resolved while it was being handed over now
ends by telling the operator to check the player for a duplicate of those items before their next join, as
the README already advised (#95). - 交易物品在发还过程中被服主处理时的控制台警告,现在会在结尾提示服主在玩家下次进服前检查其是否持有这些物品的重复副本,
与 README 的建议一致(#95)。 - Failed cleanup of an empty pending-return row now says it lists no items and removal will be retried
at a later join, rather than incorrectly sending operators to the held-return list. Confirmation
failures still report a held row. New claim labels include the server folder name before the bind
address and port, helping distinguish backends that use the same socket; the label is not a unique
server ID and falls back to the address alone if the folder cannot be resolved (#62). - 空的待返还条目删除失败时,现在会提示其不含物品、将在玩家下次进服时重试删除,不再误报暂扣。确认失败仍会提示暂扣。
新占用标签会在绑定地址与端口前附上服务器目录名,以帮助区分使用相同地址的后端;此标签不保证唯一,无法解析目录时仅保留地址(#62)。
Documentation
- Clarified the coordinated-upgrade requirement: a pre-#55 server beside an upgraded one erases a held
return's recovery record, not redelivers it. Documented why operators must interrupt hand-overs and
check the claiming server's saved player data before resolving held rows, and kept the accepted JSON
flush crash window explicit in the README (#62). - 明确混用旧版与升级版会抹去暂扣恢复记录,而非重复发还;说明处理暂扣前应停止发还并核对占用服务器上保存的玩家数据,
同时在 README 中明确已有的 JSON 写盘崩溃窗口限制(#62)。 - Documented the settings-lock allowance limits (not a database timeout; statistics skipped in a
disabled-core fallback; another plugin interrupting the server thread), that an already-open window's title
does not refresh on Minecraft 1.19.2–1.19.3, and aligned partial-reload reporting with UltiTools 6.3.2
(#68, #92, #94). - 补充说明设置锁等待额度的限制(不是数据库超时;核心停用回退时统计可能被跳过;其他插件中断服务器线程)、
Minecraft 1.19.2–1.19.3 上已打开窗口标题不会即时刷新,并使部分重载的说明与 UltiTools 6.3.2 一致
(#68、#92、#94)。
v2.0.0
Added
- A console warning for each removed setting still in
config/trade.yml. The seven settings this
version removes (trade-timeout, andmessages.toggle-on,messages.toggle-off,
messages.block-success,messages.unblock-success,messages.already-blocked,
messages.not-blocked; see### Removed) stay in the file of a server upgraded from an earlier
version, because the framework never deletes a key from an operator's file. While any of them is
there with a value, the module logs one warning per key when it is enabled and on every reload of it
(/ul reloador/ul reload UltiTrade), naming the file and the key and saying where the setting
went; the key can simply be deleted. A key left with no value (trade-timeout:or~) is not
reported: Bukkit drops it when reading the file, so it reads back as absent
(#17, #18). - 为
config/trade.yml中仍保留的每个已移除设置项输出一条控制台警告。本版本移除的七个设置项(trade-timeout,
以及messages.toggle-on、messages.toggle-off、messages.block-success、messages.unblock-success、
messages.already-blocked、messages.not-blocked,见### Removed)会保留在从旧版本升级的服务器的文件中,
因为框架从不删除运维文件中的键。只要其中任何一个还在且带有值,本模块会在启用时以及每次重载本模块时
(/ul reload或/ul reload UltiTrade)为每个键记录一条警告,指出文件、键名以及该设置的去向;直接删除该键即可。
没有值的键(trade-timeout:或~)不会被报告:Bukkit 读取文件时会丢弃它,读回时与不存在相同
(#17、#18)。
Changed
-
This version requires UltiTools 6.3.0 or later and declares
api-version: 630inplugin.yml,
up from620in the last released version, 1.0.0. Earlier frameworks cannot load this version;
update the framework before installing it. Restart the server to load the module
(/ul reloaddoes not load a new module JAR) (UltiKits/UltiTools-Reborn#544). -
本版本需要 UltiTools 6.3.0 或更高版本,并在
plugin.yml中声明api-version: 630,上一个发布版本 1.0.0
声明的是620。更早的框架无法加载本版本;请先升级框架再安装。加载本模块需要重启服务器
(/ul reload不会加载新的模块 JAR)(UltiKits/UltiTools-Reborn#544)。 -
plugin.ymlnow declaresidentify-string: ultitrade, the key of this module's entry in the
UltiCloud catalogue. The framework's update check and/upm updateskip a module that does not
declare it, so this module now takes part in both: a later published version carrying the same key
is reported at startup and can be installed with/upm update(UltiKits/UltiTools-Reborn#474). -
plugin.yml现在声明identify-string: ultitrade,即本模块在 UltiCloud 模块目录中的条目键。框架的更新检查和
/upm update会跳过未声明该键的模块,因此本模块现在会参与两者:带有同一键的更高发布版本会在启动时提示,
并可用/upm update安装(UltiKits/UltiTools-Reborn#474)。 -
Message and title settings in
config/trade.yml— the trade-window title (gui-title) and the seven
messages (messages.request-sent,request-received,request-timeout,trade-complete,
trade-cancelled,trade-disabled,player-blocked) — are written in the server's language when the
module starts, and the file is what the module shows (for examplemessages.trade-complete: '&aTrade completed!'underlanguage: en); previously they were fixed Chinese text, solanguage: enhad no
effect on them. A setting that is still built-in text — in any language, or a default an earlier
version shipped — followslanguage: it is rewritten when the module starts or after/ul reload. A
setting you edited is kept. To keep a built-in text but stop it followinglanguage, change at least
one character. Underlanguage: zhevery one of them keeps exactly the Chinese text earlier versions
shipped. The language entriesrequest_sent,request_received,trade_disabled_targetand
player_blocked, which no code reads any more, are removed; the texts written intotrade.ymlcome
frommessage_request_sent,message_request_received,message_trade_disabledand
message_player_blocked(#16). The text written is this module's built-in text: edit these settings inconfig/trade.yml; an edit of the extracted
language file does not change them (earlier versions never read them from the language file either). -
config/trade.yml中的消息与标题设置——交易界面标题(gui-title)与七条消息(messages.request-sent、
request-received、request-timeout、trade-complete、trade-cancelled、trade-disabled、player-blocked)——
在模块启动时按服务器语言写入,文件内容即模块显示的内容;此前它们是写死的中文,language: en对它们不起作用。
仍为内置文本(任一语言的内置文本,或旧版本的出厂默认值)的设置会跟随language:模块启动或执行/ul reload
后改写为当前语言的文本。你改过的设置保持不变。若想保留内置文本又不让它跟随语言,请至少改动一个字符。在
language: zh下它们都与旧版本出厂的中文文本完全相同。不再有代码读取的语言条目request_sent、request_received、
trade_disabled_target、player_blocked已删除;写入trade.yml的文本来自message_request_sent、
message_request_received、message_trade_disabled、message_player_blocked(#16)。写入的是本模块的内置文本:请在config/trade.yml中修改这些设置;修改已解压的语言文件不会改变它们(旧版本同样从不从语言文件读取它们)。 -
The replies to
/trade toggle,/trade blockand/trade unblock— trading turned on or off, a
player added to or removed from your trade blacklist, and the refusals for a player who already is
or is not on it — now come from this module's language file,lang/<language>.ymlbeside the
configfolder (entriestrade_toggle_on,trade_toggle_off,block_success,unblock_success,
already_blocked,not_blocked), so they follow the server'slanguagesetting: English under
language: en, Chinese underlanguage: zh. Previously each was a fixed Chinese sentence under
either setting. The wording is now the language file's, which changes five of the six Chinese
replies as well: the two toggle replies no longer add a second sentence about whether other players
can send you trade requests; the already-blocked and not-blocked refusals now say "already in the
blacklist" and "not in the blacklist" instead of "in your trade blacklist"; and the unblock reply is
reworded slightly ("removed from the trade blacklist"). Only the block-success reply reads exactly as
before. In English the already-blocked and not-blocked refusals say "your blacklist". The rest of the
command's text followslanguageas well; see### Fixed(#17). -
/trade toggle、/trade block和/trade unblock的回复——开启或关闭交易、把玩家加入或移出交易黑名单,
以及对方已在或不在黑名单时的拒绝提示——现在来自本模块的语言文件,即config文件夹旁的
lang/<语言>.yml(条目trade_toggle_on、trade_toggle_off、block_success、unblock_success、
already_blocked、not_blocked),因此会跟随服务器的language设置:language: en下为英文,
language: zh下为中文。此前无论哪种设置,这些回复都是固定的中文句子。措辞现以语言文件为准,六条中文回复中有五条
的措辞也随之改变:开关交易的两条回复不再附带第二句关于其他玩家能否向你发送交易请求的说明;"已经在你的交易黑名单中"
改为"已在黑名单中","不在你的交易黑名单中"改为"不在黑名单中";"从交易黑名单中移除"改为"从交易黑名单移除"。
只有拉黑成功的回复与之前完全相同。该命令的其余文本同样跟随language,见### Fixed(#17)。
Fixed
-
Re-check the shared cross-world and distance policy at acceptance using current player locations
and configuration, including clickable acceptance and reverse-request auto-accept. Refusal consumes
the request and its BossBar and starts no trade; a policy reload applies at acceptance without
invalidating requests during reload (maintainer-approved extension of #79). -
接受请求时按双方当前位置和当前配置复查跨世界及距离策略,包括聊天按钮和反向请求自动接受;拒绝时清除请求及
BossBar,不开始交易。重载后的策略在接受时生效,无须在重载时清空请求(维护者决定在 #79 内修复)。 -
allow-cross-world: falsenow refuses trade requests between worlds even withmax-distance: 0.
The world policy is checked independently of the distance limit; zero removes only the same-world
distance limit. Explicitly allowed cross-world requests remain allowed at both zero and positive
limits (#78). -
即使
max-distance: 0,allow-cross-world: false现在也会拒绝不同世界之间的交易请求。
世界限制与距离限制独立检查;0只取消同世界的距离限制。显式允许的跨世界请求在距离限制为零或正数时
仍然允许(#78)。 -
A trade's money now moves only when the economy confirms it. The trade checked each payer's balance, then withdrew and
paid without reading whether the withdrawal succeeded, so a withdrawal refused after the check (the balance changed,
for example on another server sharing the economy's database) still paid the other player, and the items still moved.
Now both payers are withdrawn first; if either withdrawal is refused or fails, whatever was withdrawn is refunded and
the whole trade is cancelled: no money, experience or item moves, no tax is taken, and both players are told the
balance changed and nothing was transferred. A payment that is refused or fails cancels the trade the same way, and a
refund that fails is logged at SEVERE naming both players, their UUIDs, the amount and the currency, and the players are
then told a balance could not be restored and an operator was notified. Every balance and
experience check now also runs before anything moves: too little experience used to cancel the trade after the money
had already moved (#58). -
交易中的金币现在只在经济插件确认后才转移。此前交易先检查余额,再扣款和付款,却不读取扣款是否成功,因此检查之后余额发生变化(例如共享经济数据库的另一台服务器上的操作)
导致扣款被拒绝时,对方仍会收到金币,物品也照常转移。现在先从双方扣款;任一方扣款被拒绝或出错时,已扣除的金额会退还,整笔交易取消:金币、经验与物品都不转移,
不收税,并告知双方余额已变化、未转移任何东西。付款被拒绝或出错时同样取消交易;退款失败时记录一条 SEVERE,写明双方玩家、其 UUID、金额与货币,并告知玩家有余额未能恢复、已通知管理员。
所有余额与经验检查现在也都在任何转移之前进行:此前经验不足会在金币已经转移之后才取消交易(#58)。 -
On servers sharing one database, a stake waiting to be returned to a player is handed over once, not again at every
server hop. A join used to decide whether an earlier hand-over had reached the player by looking in the player's
data on its own server, which another server cannot see, so a player who moved between servers was given the same
items on each. The table now records each hand-over's state: a join first marks the entry CLAIMED with one
conditional write (only one server can), and the entry is removed once the player's data save returns; the part
that did not fit becomes a new, unclaimed entry in the same transaction. An entry left CLAIMED by a crash or a failed
save is never handed over again automatically: the console warns at start-up and on every reload with the number of
such entries, and the new/trade pending list, `/trade pending ...
v1.0.0
更新日志 / Changelog
- ci: auto-release and publish on push to master
- build: update UltiTools-API dependency to 6.2.1
- ci: fix --version flag clash with Commander.js
- ci: fix publish workflow to skip test compilation on JDK 8
- test: increase test coverage from 55% to 84.4%
- chore: untrack CLAUDE.md files and add to .gitignore
- chore: add UltiCloud marketplace metadata
- ci: add UltiCloud publish workflow on release
- feat: initial commit — UltiTrade module