Repository navigation
Releases
UltiRemoteBag 2.1.0
Do not downgrade to 2.0.0 after any page has used a sixth content row. 2.0.0 shows and saves only slots
0–44 of a page, so items in slots 45–53 (the sixth row, content_rows: 6, or a page that retained six rows
after shrinking) would not be shown there, and the next save from 2.0.0 drops them. Before rolling back, empty
the sixth row of every page (or set content_rows to 5 or less and empty each page's extra rows) on this version.
使用过第 6 行储物后不要降级到 2.0.0。 2.0.0 只显示并保存每页的 0–44 号槽位,第 6 行(content_rows: 6,或缩容后保留了
6 行的页面)中 45–53 号槽位的物品在 2.0.0 中不会显示,并会在 2.0.0 的下一次保存时丢失。回退前,请先在本版本中清空每页的第 6 行
(或把 content_rows 设为 5 及以下,并清空各页保留的额外行)。
Added
- Bag page capacity is configurable with the new
content_rowssetting inconfig/remotebag.yml: 1–6 rows of
nine slots (9–54 slots), default 5 (45 slots, unchanged behaviour). Below five rows the window is smaller; at six
rows the page has two content screens inside the same window, switched with Previous/Next content screen on
toolbar columns 1 and 7. Switching keeps unsaved edits and the edit claim; Save, close,/bag save, quit and
module disable save the whole page. Shrinking never drops items: a page keeps every occupied whole row (a yellow
line says so) until those rows are emptied and the page is reopened, and the main menu'sSlots Usedshows the
real capacity. Slots 45–53 that older versions stored but never showed now appear on the second screen. A value
outside 1–6 refuses the module with a validation error; the operator's file is never rewritten. The removed
rows_per_pagekey stays ignored. Reload affects newly opened windows only (#38). - With
require_manual_save: true(#37), the unsaved-change check covers every content
screen of the page, so a change on a screen not currently shown still refuses the close; switching screens is
not leaving the page and is never refused (#38). - 背包页容量可配置:
config/remotebag.yml新增content_rows,1–6 行、每行 9 格(9–54 格),默认 5 行(45 格,行为不变)。
少于 5 行时窗口变小;6 行时同一窗口内有两个内容屏,用工具栏第 2、8 格的「上一屏/下一屏」切换,切换保留未保存的改动与编辑占用;
保存、关闭、/bag save、退出和模块停用都保存整页。缩容不会丢物品:页面保留所有有物品的整行(聊天中黄色提示说明),清空这些行并重新
打开后才缩容;主页「已用槽位」显示实际容量。旧版本存下却从未显示的 45–53 号槽位现在出现在第二屏。超出 1–6 的值会以校验错误拒绝加载
模块,不会改写服主的配置文件。已移除的rows_per_page仍被忽略。重载只影响之后新打开的窗口(#38)。 - 启用
require_manual_save: true(#37)时,未保存改动的检查覆盖该页的所有内容屏:当前未显示的屏上有改动,
关闭同样会被拒绝;在页内切换内容屏不算离开页面,不会被拒绝(#38)。 - Opt-in manual saving with the new
require_manual_savesetting inconfig/remotebag.yml(defaultfalse,
unchanged behaviour). When it istrue, closing or leaving a page with unsaved changes is refused: the window
reopens on the next tick with "Save this page before closing or leaving it", and the claim is kept. Save (or
/bag savefor your own bag) saves it. Quit and module stop still save for safety; if the window cannot reopen,
its changes are saved instead. The removedsave_on_closekey stays ignored (#37). - Start-up check for older servers. On a server below Minecraft 1.21 the module now refuses to start unless
UltiTools is 6.4.0 or later, and logs an error naming both versions ("UltiRemoteBag needs UltiTools 6.4.0 or later
on Minecraft versions below 1.21"). If either version cannot be read, it logs a warning and starts. On Minecraft
1.21 and later nothing changes (UltiKits/UltiTools-Reborn#655). - 可选的手动保存:
config/remotebag.yml新增require_manual_save(默认false,行为不变)。设为true时,关闭或离开有未保存改动的页面
会被拒绝:窗口在下一刻重新打开并提示先保存,编辑占用保留;点击「保存」(或对自己的背包使用/bag save)即可保存。退出和模块停止仍会为安全
而保存;窗口无法重新打开时改为保存其改动。已移除的save_on_close仍被忽略(#37)。 - 低版本服务器的启动检查:在低于 Minecraft 1.21 的服务器上,除非 UltiTools 为 6.4.0 或更高版本,本模块现在会拒绝启动,并在控制台记录写明
两个版本号的错误;任一版本号无法解析时只记录警告并继续启动。Minecraft 1.21 及以上不受影响(UltiKits/UltiTools-Reborn#655)。
Changed
- For plugin authors:
RemoteBagService#readPage(UUID, int)now gives up after a bounded wait (at most about
two seconds, or a sixth oflock.timeout_secondsif that is shorter) and throws
java.util.concurrent.CompletionExceptionwhen the storage read fails or times out. A failed read is never
returned as an empty page; catch the exception and retry later instead of treating the page as empty
(#57, #82). - 面向插件作者:
RemoteBagService#readPage(UUID, int)现在最多等待一段有限时间(约两秒,若lock.timeout_seconds的六分之一更短则取其值),
存储读取失败或超时时抛出java.util.concurrent.CompletionException。读取失败绝不会以空页返回;请捕获该异常并稍后重试,
不要把页面当作空页处理(#57、#82)。 - For plugin authors:
RemoteBagService#purchasePage(Player)returns aPurchaseResult(CREATED,NOT_CREATED,REFUNDED,
REFUND_FAILED);purchaseBag(Player)is unchanged and returnstrueonly forCREATED. - 面向插件作者:
RemoteBagService#purchasePage(Player)返回PurchaseResult(CREATED、NOT_CREATED、REFUNDED、
REFUND_FAILED);purchaseBag(Player)不变,只在CREATED时返回true。 - The project now ships an MIT
LICENSEfile and declares the licence in its POM (#79). - 项目现在附带 MIT
LICENSE文件,并在 POM 中声明该许可证(#79)。 - README clarifications: page saving and upgrade notes, the cross-server purchase race, editing the official
language files, and the manual-save limitation (#68, #55, #53, #83). - README 补充说明:页面保存与升级注意事项、跨服务器购买竞争、修改官方语言文件,以及手动保存的限制
(#68、#55、#53、#83)。
Fixed
- A page whose contents cannot be read is no longer opened. Reading a content page on open or Refresh waits at
most a sixth oflock.timeout_seconds(at most two seconds). An open that times out is refused with "The bag could
not be loaded. Please try again later." and releases the claim it took; a Refresh that times out keeps the shown
items, turns the window read-only and writes nothing back. Module stop now waits (bounded) for outstanding claim
releases, and the display cache is safe across threads (#57). - 内容页读取失败时不再打开。打开或刷新内容页时最多等待
lock.timeout_seconds的六分之一(上限两秒);打开超时会被拒绝,提示「背包加载失败,
请稍后重试。」,并释放本次取得的占用;刷新超时保留当前显示的物品、窗口变为只读且不回写。模块停止时会在有限时间内等待尚未完成的占用释放,
显示缓存在多线程下安全(#57)。 - A page purchase that loses a creation race is refunded. When another server sharing the database creates the
same player's next page between the purchase's read and its insert, the purchase now gives the price back with one
deposit, tells the player (yellow) and logs a warning. If the economy plugin refuses or fails the refund it is not
retried: the player is told to contact an administrator and the console logs an error naming the player, page and
amount (#81). - 购买背包页时若另一台共用数据库的服务器抢先创建了同一页,现在会以一次存款退还已扣的钱、提示玩家(黄色)并在控制台记录警告。
经济插件拒绝或退款出错时不会重试:提示玩家联系管理员,并在控制台记录写明玩家、页码和金额的错误(#81)。 - A failed redraw no longer claims the contents are unchanged. A redraw after a refused save, lost edit rights or
a settled kept write that times out now says the view could not be redrawn and may not match what is stored; the
Refresh button keeps its own message (#82). - 拒绝保存、失去编辑权或保留的写入落定后的界面重绘读取超时时,不再声称“内容未改变”,而是提示界面未能重新绘制、可能与已保存的
不一致;“刷新”按钮仍使用原提示(#82)。
v2.0.0
Added
- One bag page is edited on one server at a time when several servers share one database. Opening a page
for editing claims it in a new database table,remote_bag_claims; while another server holds the page it opens
read-only on this server, for the owner and for administrators alike, with the line "This bag page is being
edited on another server; it is open in read-only mode", and an administrator's/bag clearand/bag delete
of that page are refused as for a page in use. The claim is released when the window closes, when its player
quits and when the module stops. While the window is open, the server renews the claim on a background task, so a
stalled main thread does not lose it; another server may take a claim over only after seeing it unrenewed for a
fulllock.timeout_secondson its own clock, so a crashed server's claim lets go by itself and disagreeing clocks
change nothing. If a claim is ever lost, the window turns read-only at once and gives back the items put in
since its last save. On one server nothing changes: the owner still outranks an administrator. The table is
created on the first start; no existing table changes and nothing is migrated. Known limitation: a writer that
does not use the claim -- an older version of this module during a rolling upgrade, another plugin, a hand edit of
the table -- can still change a page under an open window; an item taken out during that session can then exist
twice (README, "Known limitations") (#54). - 多台服务器共享一个数据库时,同一背包页同一时间只能在一台服务器上编辑。 打开编辑时会在新的数据库表
remote_bag_claims中占用该页;
另一台服务器占用期间,本服务器对所有者和管理员都以只读方式打开,并提示“该背包页正在另一台服务器上编辑,当前为只读模式”,管理员对该页的
/bag clear与/bag delete也会被拒绝。窗口关闭、玩家退出、模块停止时释放占用。窗口打开期间,服务器在后台任务中续期占用,主线程卡顿
不会丢失占用;另一台服务器只有在自己的时钟上连续lock.timeout_seconds看到占用未续期后才能接手,因此崩溃服务器的占用会自行释放,
各服务器时钟不一致也没有影响。若占用丢失,窗口立即变为只读,并归还自上次保存以来放入的物品。单台服务器上的规则不变。该表在首次启动时创建;
现有表不变,也没有任何迁移。已知限制:不使用占用的写入者(滚动升级期间的旧版本模块、其他插件、手动编辑数据表)仍可能在窗口打开时改动该页,
该会话中取出的物品可能出现两份(见 README“已知限制”)(#54)。 - A bag page survives a database that does not answer. Every database call of the edit claim and of a page
save is given up on after a sixth oflock.timeout_seconds(at most two seconds while the main thread waits),
and one call that hangs no longer holds up the claims of other pages. If the claim's renewal fails or does not
answer, the window turns read-only at once and what it shows is saved as soon as the database answers. If a save
fails or does not answer -- at close, on the Save button, at quit or by/bag save-- the claim is kept, the
changes stay in memory and the same save is retried in the background until it lands; meanwhile the page is
read-only everywhere and a reopen on this server shows the kept changes. Nothing is given back while such a save
can still land. Only a save the database refuses gives back the items put in (at the next join if the player has
left). Module stop now saves the pages still open for editing, keeps trying kept saves for five seconds and logs,
with their items, those it could not write. Every page save is fenced on the claim: one database transaction
checks that the claim is still this server's and writes the page, so a save held up past another server's
takeover writes nothing, and a save that reported an error is given back only when its receipt shows it was not
written; at module stop that receipt is read behind any save still running on the database, and a save that
cannot be decided in time is logged, not given back./bag clearand/bag deleteclaim the page for their own action.
Known limitation: a kept save is held in memory and a server crash loses it, as it loses an unsaved window
(README, "Known limitations") (#54). - 数据库未响应时,背包页不再丢失改动。 占用和保存的每次数据库调用最多等待
lock.timeout_seconds的六分之一(主线程等待时最多两秒),
一次挂起的调用不再耽误其他页面的占用续期。续期失败或未响应时,窗口立即变为只读,窗口中显示的内容在数据库恢复响应后立即保存。保存失败或未响应时——
关闭窗口、点击保存按钮、退出或/bag save——保留占用,改动保留在内存中,并在后台重试同一保存直到成功;期间该页在所有服务器上只读,
在本服务器重新打开会显示保留的改动。只要这次保存仍可能完成,就不归还任何物品。
只有被数据库拒绝的保存才归还放入的物品(玩家已离开时在其下次加入时归还)。模块停止时会保存仍在编辑中打开的背包页,对保留的保存再尝试五秒,
无法写入的连同物品记录在日志中。每次保存都以占用为栅栏:同一个数据库事务确认占用仍属于本服务器并写入页面,因此在另一台服务器接手之后被耽搁的保存不会写入任何内容,
报告了错误的保存只有在其记录表明未写入时才会被归还;模块停止时,该记录会在仍在数据库上运行的保存之后读取,无法及时判定的保存只记录日志、不归还。/bag clear与/bag delete会为自身操作占用该页。已知限制:保留的保存在内存中,服务器崩溃会丢失它,
与未保存的窗口相同(见 README“已知限制”)(#54)。
Fixed
-
Bag pages on servers that share one database. A bag page changed on another server sharing the database is
no longer overwritten by an old copy held on this server, so an item taken out there no longer comes back here
(duplicated), and an item put in there is no longer lost. Each server kept every page of a player's bag in memory
from the first read -- also after an administrator only looked at another player's bag with/bag seeor
/bag list-- and wrote the whole copy back: every cached page of that player on any save, and every cached page
of every player when the module stopped. Now nothing is written from that copy. A page is saved only from its own
window, only that page, and only if the stored page is still what the window read when it opened (or last saved);
otherwise nothing is written, the console logsFailed to update bag data, the player sees the existing
"The save did not reach the database" line, and the items put into the window since it read the page are given
back to the player (what does not fit drops at their feet; one console line lists them). Creating, clearing and deleting a page are decided on what is stored
at that moment, and write only that page. Stopping or unloading the module, quitting, and/bag savewith no page
open write nothing (every change is written when it is made;/bag savestill answersBag saved manually!when
this server holds any of your pages). A copy of another player's bag is dropped when the administrator's window
closes or the command is done, unless that player is on this server (#54). -
共享同一数据库的多台服务器上的背包页。 另一台共享该数据库的服务器修改过的背包页,不会再被本服务器持有的旧副本覆盖:在那里取出的物品
不会在这里重新出现(复制),在那里放入的物品也不会丢失。此前每台服务器从首次读取起就把玩家背包的每一页保存在内存里——包括管理员只是用
/bag see或/bag list查看了别人的背包之后——并整份写回:任意一次保存都会写回该玩家所有缓存页,模块停止时还会写回所有玩家的所有缓存页。
现在不再从这份副本写入任何内容。背包页只能由它自己的窗口保存,只写这一页,并且仅当存储的内容仍是窗口打开时(或上次保存时)读到的内容时
才写入;否则不写入,控制台记录Failed to update bag data,玩家看到既有的“保存未写入数据库”提示,自窗口读取该页以来放入的物品
归还给玩家(放不下的掉落在脚下;控制台记录一行列出这些物品)。创建、清空、删除背包页都以当时存储的内容
为准,且只写这一页。停止或卸载模块、玩家退出、以及没有打开页面时的/bag save都不写入任何内容(每次改动在发生时就已写入;本服务器持有你的
背包页时,/bag save仍回复“背包已手动保存!”)。管理员查看他人背包的窗口关闭或命令结束后,该玩家背包的副本即被丢弃,除非该玩家就在本服务器上
(#54)。 -
A bag save whose stored row has been deleted in the meantime is now reported as not saved. On a MySQL
database shared by several servers, an administrator on another server who deletes a bag page at the moment
this server saves it made that save write nothing while/bag savestill answered that the bag was saved;
now the save logsFailed to update bag dataand the save is reported as failed (#50;
since #54 a save writes only its own page). -
已存储的背包行在保存时已被删除,现在会报告为未保存。多个服务器共用同一个 MySQL 数据库时,若另一台服务器上的管理员恰好在本服务器保存时
删除了某一页背包,该次保存什么也没写入,/bag save却仍回复背包已保存;现在会记录Failed to update bag data,
并且报告保存失败(#50;自 #54 起一次保存只写它自己的那一页)。 -
config/remotebag.ymlnow writes its comments in the server's language. Thirteen comments (theeconomy.*,
sound.*andlock.*settings) used to be Chinese-only, so a fresh install underlanguage: engot a file
with Chinese comments. Each is now a language-file key that the framework resolves in the server'slanguage
every time it writes the file, with an English and a Chinese entry inlang/en.ymlandlang/zh.yml. On an
existing server the comments the framework wrote on these thirteen settings, the ones earlier versions wrote
included (also the two older comments abovelock.timeout_seconds, release v1.0.0's and the later bilingual
one, #52), switch to the server's language at the next start, and after you change
languageand run a bare/ul reload; values are
untouched, and a comment you wrote yourself is kept as you wrote it (UltiKits/UltiTools-Reborn#611)
(#48). -
config/remotebag.yml的注释现在跟随服务器语言。此前有十三条注释(economy.*、sound.*、lock.*各设置)只有中文,language: en
的全新安装得到的文件注释是中文。现在每条注释都是一个语言文件键,框架每次写入文件时按服务器的language解析,lang/en.yml与lang/zh.yml
各有英文和中文条目。已有服务器上框架在这十三个设置上写下的注释(包括旧版本写下的注释,lock.timeout_seconds上方的两种旧注释——v1.0.0 版本的和之后的中英双语注释——也在内,
#52)会在下次启动时、以及你修改language并执行不带参数的/ul reload后切换为服务器语言;设置值不受影响,
你自己写的注释保持原样(UltiKits/UltiTools-Reborn#611)(#48)。 -
When an administrator has deleted one of a player's middle bag pages (for example the player keeps pages 1
and 3), the next-page icon, its price, the page limit and the page that is created now all use the same page
number, the one after the highest page the player has (page 4 in the example). Before, the icon and the price
counted pages instead and said "page 3" while page 4 was created, and at a limit of 3 the purchase took the
money and then refused to create page 4. Now the icon is not offered when the next page number is above the
limit, so nothing is charged for a page that cannot be created (#46). -
管理员删除了玩家中间的某一页背包后(例如玩家只剩第 1、3 页),下一页图标、价格、页数上限检查和实际创建的页码现在统一使用同一个页码:
玩家现有最高页的下一页(例子中为第 4 页)。此前图标和价格按「页数」计算,显示「第 3 页」而实际创建的是第 4 页;页数上限为 3 时,购买会先扣款、
再因无法创建第 4 页而失败。现在下一页页码超过上限时不再显示该图标,因此不会为无法创建的页扣款(#46)。 -
The module loads on UltiTools-API 6.3.0 again. Its start-up warning about settings removed in 6.3.0 that
are still inconfig/remotebag.ymlused to read the configuration object that 6.3.0 removes, so on 6.3.0
the module was refuse...
v1.0.0
UltiRemoteBag v1.0.0
Initial release.
Changes
- Remote ender chest access with bag locking and permissions
- Fix: replace hardcoded Chinese in BagLockService with i18n key
- Fix: replace e.printStackTrace() with logger and add cache rollback on DB failure
- Test coverage: 92.7%
- Migrated to ultikits-module-parent POM