feat: 优化世界管理与世界信息页面#5215
Conversation
Co-authored-by: 3gf8jv4dv <3gf8jv4dv@gmail.com>
# Conflicts: # HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldListItem.java # HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldListItemSkin.java
# Conflicts: # HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldManagePage.java
There was a problem hiding this comment.
Pull request overview
This PR optimizes world management and world information pages, refactoring code structure, fixing bugs, and adding new features to improve maintainability and user experience.
Changes:
- Refactored WorldManagePage to use the Skin pattern, moving UI construction from the page class to a separate Skin class
- Fixed critical bug in dimension ID mapping (Nether and End dimension IDs were incorrect)
- Added new information fields (world spawn point, saturation level) and improved time display format
- Introduced WorldRefreshable interface and updated refresh mechanism for sub-pages
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| HMCLCore/src/main/java/org/jackhuang/hmcl/util/Lang.java | Added toFloatOrNull utility method |
| HMCLCore/src/main/java/org/jackhuang/hmcl/game/World.java | Added version support methods (supportDatapacks, supportQuickPlay), changed getWorlds return type from Stream to List, made isLocked() compute on each call |
| HMCLCore/src/main/java/org/jackhuang/hmcl/launch/DefaultLauncher.java | Refactored hardcoded version checks to use World.supportQuickPlay() |
| HMCL/src/main/java/org/jackhuang/hmcl/util/ChunkBaseApp.java | Added supportEndCity() method to centralize version checking |
| HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldManagePage.java | Major refactoring: extracted UI construction to Skin class, added refresh mechanism, renamed id to versionId, introduced WorldRefreshable interface |
| HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldListPage.java | Added launch button to world list items, simplified code, improved formatting |
| HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldInfoPage.java | Fixed dimension ID mapping bug, added world spawn and saturation fields, improved time format, simplified field binding code |
| HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldBackupsPage.java | Changed from using boolean isReadOnly to BooleanProperty for reactive UI updates |
| HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DatapackListPage.java | Added toast notification for datapack reload, disabled buttons when world is running |
| HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DatapackListPageSkin.java | Bound button disable states to isReadOnlyProperty |
| HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldManageUIUtils.java | Updated exception handling to catch WorldLockedException instead of IOException |
| I18N*.properties files | Updated translations for new features (world spawn point, saturation, improved time format) |
Comments suppressed due to low confidence (2)
HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DatapackListPage.java:80
- This method overrides WorldRefreshable.refresh; it is advisable to add an Override annotation.
public void refresh() {
HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldBackupsPage.java:82
- This method overrides WorldRefreshable.refresh; it is advisable to add an Override annotation.
public void refresh() {
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
# Conflicts: # HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldListPage.java
# Conflicts: # HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldInfoPage.java
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 19 out of 19 changed files in this pull request and generated 8 comments.
Comments suppressed due to low confidence (2)
HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/DatapackListPage.java:80
- This method overrides WorldRefreshable.refresh; it is advisable to add an Override annotation.
public void refresh() {
HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/WorldBackupsPage.java:82
- This method overrides WorldRefreshable.refresh; it is advisable to add an Override annotation.
public void refresh() {
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| world.info.player.spawn=Точка возрождения | ||
| world.info.player.xp_level=Уровень опыта | ||
| world.info.random_seed=Ключ генератора мира | ||
| world.info.time=Время игры | ||
| world.info.time.format=%s дн. | ||
| world.locked=В эксплуатации |
There was a problem hiding this comment.
This locale file no longer defines world.info.time / world.info.time.format, but WorldInfoPage still uses those keys for the played-time row. This will cause missing-translation output (fallback/key shown) when running in ru. Please add updated translations (and the new world.info.spawn / world.info.player.food_saturation_level keys if you want full coverage).
| world.info.player.spawn=Ubicación de desove | ||
| world.info.player.xp_level=Nivel de experiencia | ||
| world.info.random_seed=Semilla | ||
| world.info.time=Tiempo de juego | ||
| world.info.time.format=%s días | ||
| world.locked=En uso |
There was a problem hiding this comment.
This locale file no longer defines world.info.time / world.info.time.format, but WorldInfoPage still uses those keys for the played-time row. This will cause missing-translation output (fallback/key shown) when running in es. Please add updated translations (and the new world.info.spawn / world.info.player.food_saturation_level keys if you want full coverage).
| world.info.player.spawn=موقع الظهور | ||
| world.info.player.xp_level=مستوى الخبرة | ||
| world.info.random_seed=البذرة | ||
| world.info.time=وقت اللعبة | ||
| world.info.time.format=%s أيام | ||
| world.locked=قيد الاستخدام |
There was a problem hiding this comment.
This locale file no longer defines world.info.time / world.info.time.format, but WorldInfoPage still uses those keys for the played-time row. This will cause missing-translation output (fallback/key shown) when running in ar. Please add updated translations (and the new world.info.spawn / world.info.player.food_saturation_level keys if you want full coverage).
| world.info.player.spawn=床/復生錨之所 | ||
| world.info.player.xp_level=經驗之層 | ||
| world.info.random_seed=種 | ||
| world.info.time=戲之時辰 | ||
| world.info.time.format=%s 日 | ||
| world.locked=見用 |
There was a problem hiding this comment.
This locale file no longer defines world.info.time / world.info.time.format, but WorldInfoPage still uses those keys for the played-time row. This will cause missing-translation output (fallback/key shown) when running in lzh. Please add updated translations (and the new world.info.spawn / world.info.player.food_saturation_level keys if you want full coverage).
| private void updateWorldLevelDat(boolean pageFullyNavigated) { | ||
| try { | ||
| world.reloadLevelDat(); | ||
| } catch (IOException e) { | ||
| LOG.warning("Can not load world level.dat of world: " + world.getFile(), e); | ||
| if (pageFullyNavigated) { | ||
| closePageForLoadingFail(); | ||
| } else { | ||
| this.addEventHandler(Navigator.NavigationEvent.NAVIGATED, event -> closePageForLoadingFail()); | ||
| } |
There was a problem hiding this comment.
updateWorldLevelDat(false) adds a new Navigator.NavigationEvent.NAVIGATED handler every time reloadLevelDat() fails before the page is fully navigated, and the handler is never removed. If navigation retries happen, this can accumulate handlers and trigger duplicate close/dialog actions. Consider registering a single one-shot handler (remove after first fire), or store the handler reference and avoid re-adding it if already present.
| public boolean supportDatapacks() { | ||
| return getGameVersion() != null && getGameVersion().isAtLeast("1.13", "17w43a"); | ||
| } | ||
|
|
||
| public boolean supportQuickPlay() { | ||
| return getGameVersion() != null && getGameVersion().isAtLeast("1.20", "23w14a"); | ||
| } | ||
|
|
||
| public static boolean supportQuickPlay(GameVersionNumber gameVersionNumber) { | ||
| return gameVersionNumber != null && gameVersionNumber.isAtLeast("1.20", "23w14a"); |
There was a problem hiding this comment.
PR description mentions adding supportsDatapacks() / supportsQuickPlay() methods, but the code adds supportDatapacks() / supportQuickPlay(). Please align the method names with the PR description (or update the PR description) to avoid confusion for reviewers and future contributors.
| world.info.player.spawn=Місце появи | ||
| world.info.player.xp_level=Рівень досвіду | ||
| world.info.random_seed=Насіння | ||
| world.info.time=Час гри | ||
| world.info.time.format=%s днів | ||
| world.locked=Використовується |
There was a problem hiding this comment.
This locale file no longer defines world.info.time / world.info.time.format, but WorldInfoPage still uses those keys for the played-time row. This will cause missing-translation output (fallback/key shown) when running in uk. Please add updated translations (and the new world.info.spawn / world.info.player.food_saturation_level keys if you want full coverage).


继续 #4823 对世界信息界面进行的优化
世界管理:
版本特性解析:
世界信息页面:
bug 修复:
修改:
%d 天 %d 小时 %d 分钟而不是%s 天优化:
世界列表页面:
数据包页面
World类: