Compare commits

..
Author SHA1 Message Date
Burning_TNT 8e9c2f27a1 Bump Terracotta to 0.3.14 (#4838)
* 更新 MacOS 元数据以增强本地化支持 by @burningtnt in
https://github.com/burningtnt/Terracotta/pull/69
* 重构 EasyTier 参数拼接逻辑 by @burningtnt in
https://github.com/burningtnt/Terracotta/pull/81
* 为 ET 添加 tcp://0.0.0.0:0 监听器 by @burningtnt in
https://github.com/burningtnt/Terracotta/pull/90
* 强制 ET 以 p2p_only 模式运行 by @burningtnt in
https://github.com/burningtnt/Terracotta/pull/97
* 支持联机房间码持久化 by @burningtnt in
https://github.com/burningtnt/Terracotta/pull/94
* 修复 'API c:player_profiles_list invocation failed: Host Profile is
consumed or invalid, machine_id may have conflict.' 的问题 by @burningtnt
in https://github.com/burningtnt/Terracotta/pull/98
2025-11-22 15:28:36 +08:00
mineDiamondandGlavo 8563db3654 添加对 1.21.11-pre1/2_unobfuscated 的支持 (#4829)
Co-authored-by: Glavo <zjx001202@gmail.com>
2025-11-21 22:06:51 +08:00
Glavo 2695b5c42f 使用 EdgeOne 分发 HMCL 元数据 (#4830) 2025-11-21 22:02:04 +08:00
Glavo bed87425e7 从首页打开子页面时应当打开默认标签页 (#4826) 2025-11-20 17:40:51 +08:00
Glavo d6ad1cbdf7 修复 TabHeader 相关动画问题 (#4822) 2025-11-19 15:32:18 +08:00
17 changed files with 119 additions and 94 deletions

No files matched your search

@@ -26,7 +26,6 @@ import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.util.Duration;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.construct.TabHeader;
import org.jetbrains.annotations.Nullable;
public class TransitionPane extends StackPane {
@@ -41,17 +40,6 @@ public class TransitionPane extends StackPane {
return currentNode;
}
public void bindTabHeader(TabHeader tabHeader) {
this.setContent(tabHeader.getSelectionModel().getSelectedItem().getNode(), ContainerAnimations.NONE);
FXUtils.onChange(tabHeader.getSelectionModel().selectedItemProperty(), newValue -> {
this.setContent(newValue.getNode(),
ContainerAnimations.SLIDE_UP_FADE_IN,
Motion.MEDIUM4,
Motion.EASE_IN_OUT_CUBIC_EMPHASIZED
);
});
}
public final void setContent(Node newView, AnimationProducer transition) {
setContent(newView, transition, Motion.SHORT4);
}
@@ -66,6 +54,7 @@ public class TransitionPane extends StackPane {
currentNode = newView;
if (!AnimationUtils.isAnimationEnabled() || previousNode == null || transition == ContainerAnimations.NONE) {
AnimationUtils.reset(newView, true);
getChildren().setAll(newView);
return;
}
@@ -36,12 +36,24 @@ import javafx.scene.transform.Rotate;
import javafx.scene.transform.Scale;
import javafx.util.Duration;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
import org.jackhuang.hmcl.ui.animation.Motion;
import org.jackhuang.hmcl.ui.animation.TransitionPane;
import org.jackhuang.hmcl.util.javafx.MappedObservableList;
import org.jetbrains.annotations.Nullable;
@SuppressWarnings("deprecation")
public class TabHeader extends Control implements TabControl, PageAware {
private final TransitionPane contentPane;
public TabHeader(Tab<?>... tabs) {
this(null, tabs);
}
public TabHeader(@Nullable TransitionPane contentPane, Tab<?>... tabs) {
this.contentPane = contentPane;
getStyleClass().setAll("tab-header");
if (tabs != null) {
getTabs().addAll(tabs);
@@ -49,41 +61,48 @@ public class TabHeader extends Control implements TabControl, PageAware {
}
private final ObservableList<Tab<?>> tabs = FXCollections.observableArrayList();
private final ObjectProperty<Side> side = new SimpleObjectProperty<>(Side.TOP);
@Override
public ObservableList<Tab<?>> getTabs() {
return tabs;
}
private final ObjectProperty<SingleSelectionModel<Tab<?>>> selectionModel = new SimpleObjectProperty<>(this, "selectionModel", new TabControlSelectionModel(this));
private final SingleSelectionModel<Tab<?>> selectionModel = new TabControlSelectionModel(this);
public SingleSelectionModel<Tab<?>> getSelectionModel() {
return selectionModel.get();
}
public ObjectProperty<SingleSelectionModel<Tab<?>>> selectionModelProperty() {
return selectionModel;
}
public void setSelectionModel(SingleSelectionModel<Tab<?>> selectionModel) {
this.selectionModel.set(selectionModel);
public void select(Tab<?> tab) {
select(tab, true);
}
public void select(Tab<?> tab) {
public void select(Tab<?> tab, boolean playAnimation) {
Tab<?> oldTab = getSelectionModel().getSelectedItem();
if (oldTab != null) {
if (oldTab.getNode() instanceof PageAware) {
((PageAware) oldTab.getNode()).onPageHidden();
if (oldTab.getNode() instanceof PageAware pageAware) {
pageAware.onPageHidden();
}
}
tab.initializeIfNeeded();
if (tab.getNode() instanceof PageAware) {
((PageAware) tab.getNode()).onPageShown();
if (tab.getNode() instanceof PageAware pageAware) {
pageAware.onPageShown();
}
getSelectionModel().select(tab);
if (contentPane != null) {
if (playAnimation && contentPane.getCurrentNode() != null) {
contentPane.setContent(tab.getNode(),
ContainerAnimations.SLIDE_UP_FADE_IN,
Motion.MEDIUM4,
Motion.EASE_IN_OUT_CUBIC_EMPHASIZED
);
} else {
contentPane.setContent(tab.getNode(), ContainerAnimations.NONE);
}
}
}
@Override
@@ -106,12 +125,7 @@ public class TabHeader extends Control implements TabControl, PageAware {
}
}
/**
* The position to place the tabs.
*/
public Side getSide() {
return side.get();
}
private final ObjectProperty<Side> side = new SimpleObjectProperty<>(Side.TOP);
/**
* The position of the tabs.
@@ -120,6 +134,13 @@ public class TabHeader extends Control implements TabControl, PageAware {
return side;
}
/**
* The position to place the tabs.
*/
public Side getSide() {
return side.get();
}
/**
* The position the place the tabs in this TabHeader.
*/
@@ -39,7 +39,6 @@ import org.jackhuang.hmcl.ui.WeakListenerHolder;
import org.jackhuang.hmcl.ui.animation.TransitionPane;
import org.jackhuang.hmcl.ui.construct.AdvancedListBox;
import org.jackhuang.hmcl.ui.construct.MessageDialogPane;
import org.jackhuang.hmcl.ui.construct.TabControl;
import org.jackhuang.hmcl.ui.construct.TabHeader;
import org.jackhuang.hmcl.ui.decorator.DecoratorAnimatedPage;
import org.jackhuang.hmcl.ui.decorator.DecoratorPage;
@@ -99,12 +98,11 @@ public class DownloadPage extends DecoratorAnimatedPage implements DecoratorPage
resourcePackTab.setNodeSupplier(loadVersionFor(() -> HMCLLocalizedDownloadListPage.ofResourcePack((profile, version, file) -> download(profile, version, file, "resourcepacks"), true)));
shaderTab.setNodeSupplier(loadVersionFor(() -> new DownloadListPage(ModrinthRemoteModRepository.SHADER_PACKS, (profile, version, file) -> download(profile, version, file, "shaderpacks"), true)));
worldTab.setNodeSupplier(loadVersionFor(() -> new DownloadListPage(CurseForgeRemoteModRepository.WORLDS)));
tab = new TabHeader(newGameTab, modpackTab, modTab, resourcePackTab, shaderTab, worldTab);
tab = new TabHeader(transitionPane, newGameTab, modpackTab, modTab, resourcePackTab, shaderTab, worldTab);
Profiles.registerVersionsListener(this::loadVersions);
tab.select(newGameTab);
transitionPane.bindTabHeader(tab);
AdvancedListBox sideBar = new AdvancedListBox()
.startCategory(i18n("download.game").toUpperCase(Locale.ROOT))
@@ -121,13 +119,6 @@ public class DownloadPage extends DecoratorAnimatedPage implements DecoratorPage
setCenter(transitionPane);
}
private void selectTabIfCurseForgeAvailable(TabControl.Tab<?> newTab) {
if (CurseForgeRemoteModRepository.isAvailable())
tab.select(newTab);
else
Controllers.dialog(i18n("download.curseforge.unavailable"));
}
private static <T extends Node> Supplier<T> loadVersionFor(Supplier<T> nodeSupplier) {
return () -> {
T node = nodeSupplier.get();
@@ -202,20 +193,20 @@ public class DownloadPage extends DecoratorAnimatedPage implements DecoratorPage
}
public void showGameDownloads() {
tab.select(newGameTab);
tab.select(newGameTab, false);
}
public void showModpackDownloads() {
tab.select(modpackTab);
tab.select(modpackTab, false);
}
public DownloadListPage showModDownloads() {
tab.select(modTab);
tab.select(modTab, false);
return modTab.getNode();
}
public void showWorldDownloads() {
tab.select(worldTab);
tab.select(worldTab, false);
}
private static final class DownloadNavigator implements Navigation {
@@ -55,11 +55,10 @@ public class LauncherSettingsPage extends DecoratorAnimatedPage implements Decor
helpTab.setNodeSupplier(HelpPage::new);
feedbackTab.setNodeSupplier(FeedbackPage::new);
aboutTab.setNodeSupplier(AboutPage::new);
tab = new TabHeader(gameTab, javaManagementTab, settingsTab, personalizationTab, downloadTab, helpTab, feedbackTab, aboutTab);
tab = new TabHeader(transitionPane, gameTab, javaManagementTab, settingsTab, personalizationTab, downloadTab, helpTab, feedbackTab, aboutTab);
tab.select(gameTab);
addEventHandler(Navigator.NavigationEvent.NAVIGATED, event -> gameTab.getNode().loadVersion(Profiles.getSelectedProfile(), null));
transitionPane.bindTabHeader(tab);
AdvancedListBox sideBar = new AdvancedListBox()
.addNavigationDrawerTab(tab, gameTab, i18n("settings.type.global.manage"), SVG.STADIA_CONTROLLER, SVG.STADIA_CONTROLLER_FILL)
@@ -90,11 +89,11 @@ public class LauncherSettingsPage extends DecoratorAnimatedPage implements Decor
public void showGameSettings(Profile profile) {
gameTab.getNode().loadVersion(profile, null);
tab.select(gameTab);
tab.select(gameTab, false);
}
public void showFeedback() {
tab.select(feedbackTab);
tab.select(feedbackTab, false);
}
@Override
@@ -177,7 +177,10 @@ public class RootPage extends DecoratorAnimatedPage implements DecoratorPage {
downloadItem.setLeftGraphic(wrap(SVG.DOWNLOAD));
downloadItem.setActionButtonVisible(false);
downloadItem.setTitle(i18n("download"));
downloadItem.setOnAction(e -> Controllers.navigate(Controllers.getDownloadPage()));
downloadItem.setOnAction(e -> {
Controllers.getDownloadPage().showGameDownloads();
Controllers.navigate(Controllers.getDownloadPage());
});
FXUtils.installFastTooltip(downloadItem, i18n("download.hint"));
if (AnimationUtils.isAnimationEnabled()) {
FXUtils.prepareOnMouseEnter(downloadItem, Controllers::prepareDownloadPage);
@@ -188,7 +191,10 @@ public class RootPage extends DecoratorAnimatedPage implements DecoratorPage {
launcherSettingsItem.setLeftGraphic(wrap(SVG.SETTINGS));
launcherSettingsItem.setActionButtonVisible(false);
launcherSettingsItem.setTitle(i18n("settings"));
launcherSettingsItem.setOnAction(e -> Controllers.navigate(Controllers.getSettingsPage()));
launcherSettingsItem.setOnAction(e -> {
Controllers.getSettingsPage().showGameSettings(Profiles.getSelectedProfile());
Controllers.navigate(Controllers.getSettingsPage());
});
if (AnimationUtils.isAnimationEnabled()) {
FXUtils.prepareOnMouseEnter(launcherSettingsItem, Controllers::prepareSettingsPage);
}
@@ -56,9 +56,8 @@ public class TerracottaPage extends DecoratorAnimatedPage implements DecoratorPa
public TerracottaPage() {
statusPage.setNodeSupplier(TerracottaControllerPage::new);
tab = new TabHeader(statusPage);
tab = new TabHeader(transitionPane, statusPage);
tab.select(statusPage);
transitionPane.bindTabHeader(tab);
BorderPane left = new BorderPane();
FXUtils.setLimitWidth(left, 200);
@@ -71,13 +71,11 @@ public class VersionPage extends DecoratorAnimatedPage implements DecoratorPage
worldListTab.setNodeSupplier(loadVersionFor(WorldListPage::new));
schematicsTab.setNodeSupplier(loadVersionFor(SchematicsPage::new));
tab = new TabHeader(versionSettingsTab, installerListTab, modListTab, worldListTab, schematicsTab);
tab = new TabHeader(transitionPane, versionSettingsTab, installerListTab, modListTab, worldListTab, schematicsTab);
tab.select(versionSettingsTab);
addEventHandler(Navigator.NavigationEvent.NAVIGATED, this::onNavigated);
tab.select(versionSettingsTab);
transitionPane.bindTabHeader(tab);
listenerHolder.add(EventBus.EVENT_BUS.channel(RefreshedVersionsEvent.class).registerWeak(event -> checkSelectedVersion(), EventPriority.HIGHEST));
}
@@ -107,6 +105,10 @@ public class VersionPage extends DecoratorAnimatedPage implements DecoratorPage
};
}
public void showInstanceSettings() {
tab.select(versionSettingsTab, false);
}
public void setVersion(String version, Profile profile) {
this.version.set(new Profile.ProfileVersion(profile, version));
}
@@ -287,6 +287,7 @@ public final class Versions {
public static void modifyGameSettings(Profile profile, String version) {
Controllers.getVersionPage().setVersion(version, profile);
Controllers.getVersionPage().showInstanceSettings();
// VersionPage.loadVersion will be invoked after navigation
Controllers.navigate(Controllers.getVersionPage());
}
@@ -64,15 +64,13 @@ public final class WorldManagePage extends DecoratorAnimatedPage implements Deco
this.world = world;
this.backupsDir = backupsDir;
this.worldInfoTab.setNodeSupplier(() -> new WorldInfoPage(this));
this.worldBackupsTab.setNodeSupplier(() -> new WorldBackupsPage(this));
this.datapackTab.setNodeSupplier(() -> new DatapackListPage(this));
this.state = new SimpleObjectProperty<>(State.fromTitle(i18n("world.manage.title", world.getWorldName())));
this.header = new TabHeader(worldInfoTab, worldBackupsTab);
worldInfoTab.setNodeSupplier(() -> new WorldInfoPage(this));
worldBackupsTab.setNodeSupplier(() -> new WorldBackupsPage(this));
datapackTab.setNodeSupplier(() -> new DatapackListPage(this));
this.header = new TabHeader(transitionPane, worldInfoTab, worldBackupsTab);
header.select(worldInfoTab);
transitionPane.bindTabHeader(header);
setCenter(transitionPane);
@@ -30,7 +30,7 @@ public final class MinecraftWiki {
private static final Pattern SNAPSHOT_PATTERN = Pattern.compile("^[0-9]{2}w[0-9]{2}.+$");
public static String getWikiLink(SupportedLocale locale, GameRemoteVersion version) {
String wikiVersion = version.getSelfVersion();
String wikiVersion = StringUtils.removeSuffix(version.getSelfVersion(), "_unobfuscated");
var gameVersion = GameVersionNumber.asGameVersion(wikiVersion);
if (locale.getLocale().getLanguage().equals("lzh")) {
@@ -80,8 +80,6 @@ public final class MinecraftWiki {
if (SNAPSHOT_PATTERN.matcher(wikiVersion).matches()) {
if (wikiVersion.equals("22w13oneblockatatime"))
wikiVersion = "22w13oneBlockAtATime";
else
wikiVersion = StringUtils.removeSuffix(wikiVersion, "_unobfuscated");
return locale.i18n("wiki.version.game.snapshot", wikiVersion) + variantSuffix;
}
}
+14 -14
View File
@@ -1,21 +1,21 @@
{
"version_legacy": "0\\.3\\.([89]-rc\\.([0-9]|10)|10|11|12)",
"version_legacy": "0\\.3\\.([89]-rc\\.([0-9]|10)|(1[0-3]))",
"version_recent": [
"0.3.12"
"0.3.13"
],
"version_latest": "0.3.13",
"version_latest": "0.3.14",
"classifiers": {
"freebsd-x86_64": "sha256:0713e54ee552496416bda9d9e814e33a8950ca8f321f5b3c6dd2e07e79b0e3af",
"linux-arm64": "sha256:61affc46035337c182adeca3671b4cf4cc59c7b4e73039899f35416f7d00ad94",
"linux-x86_64": "sha256:9399e1627b77d518950e66d944c9a4b70c20d2e13ca2c0e2fed0ded637e7ae06",
"linux-loongarch64": "sha256:f3eb4c40dfccc25b5b355298c776abe3d399afb57a2af38803dd78089f0c182e",
"linux-riscv64": "sha256:26f95f8b5f83746c9cf9a8362ce0ef793ede8515897a1ba15e5e6f93c3d39533",
"macos-arm64": "sha256:35ba271c7dc924e91c2fdd8c1cabeff2ce3d060836748a7a07162b0a5900e8d5",
"macos-arm64.pkg": "sha256:90a613ec69f28713fe06188247c57b7cc91743c95112de5aed85ea252103beaa",
"macos-x86_64": "sha256:45b420b15a32d5450794a9776cf45a217871cf4333b29b65a35d7358c806b5b1",
"macos-x86_64.pkg": "sha256:587623becb3593ccb5fe542a201a67ab3a4029dfa847fcef758faff7ba6d38d5",
"windows-arm64.exe": "sha256:bd4e1acf2f304761cdabddd9ade94d046534f4c024bc3026ac98e6be58c2bc22",
"windows-x86_64.exe": "sha256:b89599bbcc92b00222cfc6f2e5ef636b7daf192c96efba1049a892e6cb59ee70"
"freebsd-x86_64": "sha256:ff8c50b701e55fde9701a1f7fbe9d7317b24087c28ca6337ba9d695c53ad499a",
"linux-arm64": "sha256:6912a14255cdeedee512244c686dd7f80dcc45d8dfbe129ea4ea3f1b22d3de60",
"linux-x86_64": "sha256:9b13f51dc41c5112f2ab163df5c0dccdff3d22deb793a6698c013e9c09badd00",
"linux-loongarch64": "sha256:729ca24ef643547b6a3917520ec3335b92e226ad1884c85d6bb6c2cfa917cb03",
"linux-riscv64": "sha256:afbd8cffeacc47431f18c3ae659f7a308e1d3f2efab0ab9c5ece5176d068bf30",
"macos-arm64": "sha256:9ed9c7a35b01dce440135c91e4a5e617d84f6c8ba13a117d13a2796dc69584f5",
"macos-arm64.pkg": "sha256:49dbebd608c4036c260f09d4005dedaacb26fc1582b10479ed51476baa48f4a9",
"macos-x86_64": "sha256:40a44703237b0a194b0fb18075e3b2361ace8f4319b60269cb56c5548d2afb3a",
"macos-x86_64.pkg": "sha256:95a9de782b9c3a352ae6ec702c2fc4ca34ba807e8e4a768e61902a0c78391332",
"windows-arm64.exe": "sha256:8428c6bc6228213c5f645ab3dd0f3b684da515be103ee53d5bdc4adf59fc8a5f",
"windows-x86_64.exe": "sha256:942b91888264e1c96a10b7c94bd134f4b10d3e352e3c731def0ff6a3069c8221"
},
"downloads": [
"https://github.com/burningtnt/Terracotta/releases/download/v${version}/terracotta-${version}-${classifier}"
@@ -82,8 +82,8 @@ public final class BMCLAPIDownloadProvider implements DownloadProvider {
pair("https://authlib-injector.yushi.moe", apiRoot + "/mirrors/authlib-injector"),
pair("https://repo1.maven.org/maven2", "https://mirrors.cloud.tencent.com/nexus/repository/maven-public"),
pair("https://repo.maven.apache.org/maven2", "https://mirrors.cloud.tencent.com/nexus/repository/maven-public"),
pair("https://hmcl-dev.github.io/metadata/cleanroom", "https://alist.8mi.tech/d/mirror/HMCL-Metadata/Auto/cleanroom"),
pair("https://hmcl-dev.github.io/metadata/fmllibs", "https://alist.8mi.tech/d/mirror/HMCL-Metadata/Auto/fmllibs"),
pair("https://hmcl.glavo.site/metadata/cleanroom", "https://alist.8mi.tech/d/mirror/HMCL-Metadata/Auto/cleanroom"),
pair("https://hmcl.glavo.site/metadata/fmllibs", "https://alist.8mi.tech/d/mirror/HMCL-Metadata/Auto/fmllibs"),
pair("https://zkitefly.github.io/unlisted-versions-of-minecraft", "https://alist.8mi.tech/d/mirror/unlisted-versions-of-minecraft/Auto")
// // https://github.com/mcmod-info-mirror/mcim-rust-api
// pair("https://api.modrinth.com", "https://mod.mcimirror.top/modrinth"),
@@ -27,8 +27,8 @@ import java.util.Collections;
public final class CleanroomVersionList extends VersionList<CleanroomRemoteVersion> {
private final DownloadProvider downloadProvider;
private static final String LOADER_LIST_URL = "https://hmcl-dev.github.io/metadata/cleanroom/index.json";
private static final String INSTALLER_URL = "https://hmcl-dev.github.io/metadata/cleanroom/files/cleanroom-%s-installer.jar";
private static final String LOADER_LIST_URL = "https://hmcl.glavo.site/metadata/cleanroom/index.json";
private static final String INSTALLER_URL = "https://hmcl.glavo.site/metadata/cleanroom/files/cleanroom-%s-installer.jar";
public CleanroomVersionList(DownloadProvider downloadProvider) {
this.downloadProvider = downloadProvider;
@@ -96,5 +96,5 @@ public final class ForgeVersionList extends VersionList<ForgeRemoteVersion> {
});
}
public static final URI FORGE_LIST = URI.create("https://hmcl-dev.github.io/metadata/forge/");
public static final URI FORGE_LIST = URI.create("https://hmcl.glavo.site/metadata/forge/");
}
@@ -149,7 +149,7 @@ public final class GameLibrariesTask extends Task<Void> {
Path file = libDir.resolve(fmlLib.name);
if (shouldDownloadFMLLib(fmlLib, file)) {
List<URI> uris = dependencyManager.getDownloadProvider()
.injectURLWithCandidates(fmlLib.getDownloadURI());
.injectURLWithCandidates(fmlLib.downloadUrl());
dependencies.add(new FileDownloadTask(uris, file)
.withCounter("hmcl.install.libraries"));
}
@@ -193,9 +193,12 @@ public final class GameLibrariesTask extends Task<Void> {
if (forgeVersion.startsWith("7.8.1.")) {
return List.of(
new FMLLib("argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51"),
new FMLLib("guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a"),
new FMLLib("asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58"),
new FMLLib("bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65"),
new FMLLib("guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a",
"https://repo1.maven.org/maven2/com/google/guava/guava/14.0-rc3/guava-14.0-rc3.jar"),
new FMLLib("asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58",
"https://repo1.maven.org/maven2/org/ow2/asm/asm-all/4.1/asm-all-4.1.jar"),
new FMLLib("bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65",
"https://repo1.maven.org/maven2/org/bouncycastle/bcprov-jdk15on/1.48/bcprov-jdk15on-1.48.jar"),
new FMLLib("deobfuscation_data_1.5.2.zip", "446e55cd986582c70fcf12cb27bc00114c5adfd9"),
new FMLLib("scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85")
);
@@ -204,9 +207,9 @@ public final class GameLibrariesTask extends Task<Void> {
return null;
}
private record FMLLib(String name, String sha1) {
public String getDownloadURI() {
return "https://hmcl-dev.github.io/metadata/fmllibs/" + name;
private record FMLLib(String name, String sha1, String downloadUrl) {
FMLLib(String name, String sha1) {
this(name, sha1, "https://hmcl.glavo.site/metadata/fmllibs/" + name);
}
}
}
@@ -1,5 +1,19 @@
{
"versions": [
{
"id": "1.21.11-pre2_unobfuscated",
"type": "unobfuscated",
"url": "https://piston-meta.mojang.com/v1/packages/2955ce0af0512fdfe53ff0740b017344acf6f397/1.21.11-pre2_unobfuscated.json",
"time": "2025-11-21T12:07:21+00:00",
"releaseTime": "2025-11-21T12:07:21+00:00"
},
{
"id": "1.21.11-pre1_unobfuscated",
"type": "unobfuscated",
"url": "https://piston-meta.mojang.com/v1/packages/9c267f8dda2728bae55201a753cdd07b584709f1/1.21.11-pre1_unobfuscated.json",
"time": "2025-11-19T08:30:46+00:00",
"releaseTime": "2025-11-19T08:30:46+00:00"
},
{
"id": "25w46a_unobfuscated",
"type": "unobfuscated",
@@ -856,4 +856,8 @@
25w45a
25w45a_unobfuscated
25w46a
25w46a_unobfuscated
25w46a_unobfuscated
1.21.11-pre1
1.21.11-pre1_unobfuscated
1.21.11-pre2
1.21.11-pre2_unobfuscated