Skip to content

feat #3763: add April Fool's Day version category #3905

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
private final JFXCheckBox chkRelease;
private final JFXCheckBox chkSnapshot;
private final JFXCheckBox chkOld;
private final JFXCheckBox chkAprilFools;
private final ComponentList centrePane;
private final StackPane center;

Expand Down Expand Up @@ -139,7 +140,10 @@ public VersionsPage(Navigation navigation, String title, String gameVersion, Dow
chkOld = new JFXCheckBox(i18n("version.game.old"));
HBox.setMargin(chkOld, new Insets(10, 0, 10, 0));

checkPane.getChildren().setAll(chkRelease, chkSnapshot, chkOld);
chkAprilFools = new JFXCheckBox(i18n("version.game.aprilfools"));
HBox.setMargin(chkAprilFools, new Insets(10, 0, 10, 0));

checkPane.getChildren().setAll(chkRelease, chkSnapshot, chkOld, chkAprilFools);
}

list = new JFXListView<>();
Expand All @@ -151,18 +155,19 @@ public VersionsPage(Navigation navigation, String title, String gameVersion, Dow
HBox refreshPane = new HBox();
refreshPane.setAlignment(Pos.CENTER_RIGHT);

btnRefresh = new JFXButton(i18n("button.refresh"));
btnRefresh = new JFXButton();
btnRefresh.getStyleClass().add("jfx-tool-bar-button");
btnRefresh.setOnAction(e -> onRefresh());

JFXButton btnSearch = new JFXButton(i18n("search"));
JFXButton btnSearch = new JFXButton();
btnSearch.getStyleClass().add("jfx-tool-bar-button");
btnSearch.setGraphic(wrap(SVG.SEARCH.createIcon(Theme.blackFill(), -1)));

searchBar = new HBox();
{
searchBar.setAlignment(Pos.CENTER);
searchBar.setPadding(new Insets(0, 5, 0, 0));
searchBar.setPadding(new Insets(0, 0, 0, 0));
searchBar.setMaxWidth(130);

JFXTextField searchField = new JFXTextField();
searchField.setPromptText(i18n("search"));
Expand Down Expand Up @@ -235,6 +240,8 @@ public VersionsPage(Navigation navigation, String title, String gameVersion, Dow
chkSnapshot.setVisible(hasType);
chkOld.setManaged(hasType);
chkOld.setVisible(hasType);
chkAprilFools.setManaged(hasType);
chkAprilFools.setVisible(hasType);

if (hasType) {
centrePane.getContent().setAll(toolbarPane, list);
Expand Down Expand Up @@ -269,6 +276,7 @@ public VersionsPage(Navigation navigation, String title, String gameVersion, Dow
chkRelease.selectedProperty().addListener(listener);
chkSnapshot.selectedProperty().addListener(listener);
chkOld.selectedProperty().addListener(listener);
chkAprilFools.selectedProperty().addListener(listener);
queryString.addListener(listener);

btnRefresh.setGraphic(wrap(SVG.REFRESH.createIcon(Theme.blackFill(), -1)));
Expand Down Expand Up @@ -297,6 +305,8 @@ private List<RemoteVersion> loadVersions() {
return chkSnapshot.isSelected();
case OLD:
return chkOld.isSelected();
case APRILFOOLS:
return chkAprilFools.isSelected();
default:
return true;
}
Expand All @@ -321,6 +331,7 @@ public void refresh() {
chkRelease.setSelected(true);
chkSnapshot.setSelected(true);
chkOld.setSelected(true);
chkAprilFools.setSelected(true);
} else {
list.getItems().setAll(items);
}
Expand Down Expand Up @@ -418,6 +429,16 @@ public void updateItem(RemoteVersion remoteVersion, boolean empty) {
content.setImage(VersionIconType.COMMAND.getIcon());
content.setExternalLink(i18n("wiki.version.game.snapshot", remoteVersion.getGameVersion()));
break;
case APRILFOOLS:
content.getTags().setAll(i18n("version.game.aprilfools"));
content.setImage(VersionIconType.COMMAND.getIcon());
if (remoteVersion.getGameVersion().startsWith("2.0")) {
content.setExternalLink(i18n("wiki.version.game.snapshot", "2.0"));
Copy link
Preview

Copilot AI May 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The APRILFOOLS case reuses the snapshot wiki link; consider defining a dedicated translation key or URL (e.g., wiki.version.game.aprilfools) to avoid confusion for end users.

Copilot uses AI. Check for mistakes.

}
else {
content.setExternalLink(i18n("wiki.version.game.snapshot", remoteVersion.getGameVersion()));
}
break;
default:
content.getTags().setAll(i18n("version.game.old"));
content.setImage(VersionIconType.CRAFT_TABLE.getIcon());
Expand Down
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1351,6 +1351,7 @@ version.empty=No Instances
version.empty.add=Add new instance
version.empty.launch=No available instances. Clicking "OK" will take you to the "Download" page.\n\nYou can also download the game or switch game directories via the "Download" or "All Instances" buttons on the HMCL homepage.
version.empty.hint=There are no Minecraft instances here.\nYou can try switching to another game directory or clicking here to download one.
version.game.aprilfools=AprilFools
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
version.game.aprilfools=AprilFools
version.game.aprilfools=April Fools

Copy link
Preview

Copilot AI May 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The English label "AprilFools" lacks spacing; consider changing it to "April Fools" or "April Fool's" for better readability.

Suggested change
version.game.aprilfools=AprilFools
version.game.aprilfools=April Fools

Copilot uses AI. Check for mistakes.

version.game.old=Historical
version.game.release=Release
version.game.releases=Releases
Expand Down
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1143,6 +1143,7 @@ version.empty=沒有遊戲版本
version.empty.add=進入下載頁安裝遊戲
version.empty.launch=沒有可啟動的遊戲。點擊「確定」將進入「下載」頁面。\n你也可以點擊 HMCL 主介面左側的「下載」按鈕安裝遊戲,或在「實例清單」切換遊戲目錄。
version.empty.hint=沒有已安裝的遊戲。\n你可以切換其他遊戲目錄,或者點擊此處進入遊戲下載頁面。
version.game.aprilfools=愚人節
version.game.old=遠古版
version.game.release=正式版
version.game.releases=正式版
Expand Down
1 change: 1 addition & 0 deletions HMCL/src/main/resources/assets/lang/I18N_zh_CN.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1153,6 +1153,7 @@ version.empty=没有游戏版本
version.empty.add=进入下载页安装游戏
version.empty.launch=没有可启动的游戏。点击“确定”将进入“下载”页面。\n你也可以点击 HMCL 主界面左侧的“下载”按钮安装游戏,或在“版本列表”切换游戏文件夹。
version.empty.hint=没有已安装的游戏。\n你可以切换其他游戏文件夹,或者点击此处进入游戏下载页面。
version.game.aprilfools=愚人节
version.game.old=远古版
version.game.release=正式版
version.game.releases=正式版
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ public enum Type {
RELEASE,
SNAPSHOT,
OLD,
PENDING
PENDING,
APRILFOOLS
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@
import org.jackhuang.hmcl.util.Immutable;

import java.time.Instant;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
*
Expand All @@ -38,7 +41,7 @@ public final class GameRemoteVersion extends RemoteVersion {
private final ReleaseType type;

public GameRemoteVersion(String gameVersion, String selfVersion, List<String> url, ReleaseType type, Instant releaseDate) {
super(LibraryAnalyzer.LibraryType.MINECRAFT.getPatchId(), gameVersion, selfVersion, releaseDate, getReleaseType(type), url);
super(LibraryAnalyzer.LibraryType.MINECRAFT.getPatchId(), gameVersion, selfVersion, releaseDate, getReleaseType(type, releaseDate, gameVersion), url);
this.type = type;
}

Expand All @@ -59,8 +62,17 @@ public int compareTo(RemoteVersion o) {
return o.getReleaseDate().compareTo(getReleaseDate());
}

private static Type getReleaseType(ReleaseType type) {
if (type == null) return Type.UNCATEGORIZED;
private static Type getReleaseType(ReleaseType type, Instant releaseDate, String gameVersion) {
if (type == null || releaseDate == null || gameVersion == null) return Type.UNCATEGORIZED;
if (gameVersion.startsWith("2.0")) return Type.APRILFOOLS;
Copy link
Preview

Copilot AI May 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardcoded prefix "2.0" is a magic string; consider extracting it into a descriptive constant (e.g., APRIL_FOOLS_VERSION_PREFIX) to improve readability.

Suggested change
if (gameVersion.startsWith("2.0")) return Type.APRILFOOLS;
if (gameVersion.startsWith(APRIL_FOOLS_VERSION_PREFIX)) return Type.APRILFOOLS;

Copilot uses AI. Check for mistakes.

if (gameVersion.startsWith("1.RV")) return Type.APRILFOOLS;
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.setTime(Date.from(releaseDate));
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
Comment on lines +69 to +72
Copy link
Preview

Copilot AI May 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses the legacy Calendar/Date API; consider using java.time (e.g., releaseDate.atZone(ZoneOffset.UTC)) for clearer and more modern date handling.

Suggested change
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.setTime(Date.from(releaseDate));
int month = cal.get(Calendar.MONTH);
int day = cal.get(Calendar.DAY_OF_MONTH);
int month = releaseDate.atZone(ZoneOffset.UTC).getMonthValue() - 1; // Adjust to match Calendar.MONTH
int day = releaseDate.atZone(ZoneOffset.UTC).getDayOfMonth();

Copilot uses AI. Check for mistakes.

if (month == Calendar.APRIL && day == 1) {
return Type.APRILFOOLS;
}
switch (type) {
case RELEASE:
return Type.RELEASE;
Expand All @@ -70,6 +82,8 @@ private static Type getReleaseType(ReleaseType type) {
return Type.UNCATEGORIZED;
case PENDING:
return Type.PENDING;
case APRILFOOLS:
return Type.APRILFOOLS;
default:
return Type.OLD;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* @author huangyuhui
*/
public enum ReleaseType {
APRILFOOLS("aprilfools"),
RELEASE("release"),
SNAPSHOT("snapshot"),
MODIFIED("modified"),
Expand Down