May fix RemoteVersion not found exception
This commit is contained in:
@@ -24,6 +24,7 @@ import javafx.scene.layout.StackPane;
|
|||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import org.jackhuang.hmcl.Main;
|
import org.jackhuang.hmcl.Main;
|
||||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||||
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
import org.jackhuang.hmcl.game.GameRepository;
|
import org.jackhuang.hmcl.game.GameRepository;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
import org.jackhuang.hmcl.ui.wizard.WizardController;
|
||||||
@@ -31,6 +32,7 @@ import org.jackhuang.hmcl.ui.wizard.WizardPage;
|
|||||||
import org.jackhuang.hmcl.util.Lang;
|
import org.jackhuang.hmcl.util.Lang;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import static org.jackhuang.hmcl.Main.i18n;
|
import static org.jackhuang.hmcl.Main.i18n;
|
||||||
|
|
||||||
@@ -101,24 +103,28 @@ class AdditionalInstallersPage extends StackPane implements WizardPage {
|
|||||||
return Main.i18n("settings.tabs.installers");
|
return Main.i18n("settings.tabs.installers");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getVersion(String id) {
|
||||||
|
return Optional.ofNullable(controller.getSettings().get(id)).map(it -> (RemoteVersion<?>) it).map(RemoteVersion::getSelfVersion).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNavigate(Map<String, Object> settings) {
|
public void onNavigate(Map<String, Object> settings) {
|
||||||
lblGameVersion.setText(Main.i18n("install.new_game.current_game_version") + ": " + provider.getGameVersion());
|
lblGameVersion.setText(Main.i18n("install.new_game.current_game_version") + ": " + provider.getGameVersion());
|
||||||
btnForge.setDisable(provider.getForge() != null);
|
btnForge.setDisable(provider.getForge() != null);
|
||||||
if (provider.getForge() != null || controller.getSettings().containsKey("forge"))
|
if (provider.getForge() != null || controller.getSettings().containsKey("forge"))
|
||||||
lblForge.setText(Main.i18n("install.installer.version", Main.i18n("install.installer.forge")) + ": " + Lang.nonNull(provider.getForge(), controller.getSettings().get("forge")));
|
lblForge.setText(Main.i18n("install.installer.version", Main.i18n("install.installer.forge")) + ": " + Lang.nonNull(provider.getForge(), getVersion("forge")));
|
||||||
else
|
else
|
||||||
lblForge.setText(Main.i18n("install.installer.not_installed", Main.i18n("install.installer.forge")));
|
lblForge.setText(Main.i18n("install.installer.not_installed", Main.i18n("install.installer.forge")));
|
||||||
|
|
||||||
btnLiteLoader.setDisable(provider.getLiteLoader() != null);
|
btnLiteLoader.setDisable(provider.getLiteLoader() != null);
|
||||||
if (provider.getLiteLoader() != null || controller.getSettings().containsKey("liteloader"))
|
if (provider.getLiteLoader() != null || controller.getSettings().containsKey("liteloader"))
|
||||||
lblLiteLoader.setText(Main.i18n("install.installer.version", Main.i18n("install.installer.liteloader")) + ": " + Lang.nonNull(provider.getLiteLoader(), controller.getSettings().get("liteloader")));
|
lblLiteLoader.setText(Main.i18n("install.installer.version", Main.i18n("install.installer.liteloader")) + ": " + Lang.nonNull(provider.getLiteLoader(), getVersion("liteloader")));
|
||||||
else
|
else
|
||||||
lblLiteLoader.setText(Main.i18n("install.installer.not_installed", Main.i18n("install.installer.liteloader")));
|
lblLiteLoader.setText(Main.i18n("install.installer.not_installed", Main.i18n("install.installer.liteloader")));
|
||||||
|
|
||||||
btnOptiFine.setDisable(provider.getOptiFine() != null);
|
btnOptiFine.setDisable(provider.getOptiFine() != null);
|
||||||
if (provider.getOptiFine() != null || controller.getSettings().containsKey("optifine"))
|
if (provider.getOptiFine() != null || controller.getSettings().containsKey("optifine"))
|
||||||
lblOptiFine.setText(Main.i18n("install.installer.version", Main.i18n("install.installer.optifine")) + ": " + Lang.nonNull(provider.getOptiFine(), controller.getSettings().get("optifine")));
|
lblOptiFine.setText(Main.i18n("install.installer.version", Main.i18n("install.installer.optifine")) + ": " + Lang.nonNull(provider.getOptiFine(), getVersion("optifine")));
|
||||||
else
|
else
|
||||||
lblOptiFine.setText(Main.i18n("install.installer.not_installed", Main.i18n("install.installer.optifine")));
|
lblOptiFine.setText(Main.i18n("install.installer.not_installed", Main.i18n("install.installer.optifine")));
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import javafx.scene.Node;
|
|||||||
import org.jackhuang.hmcl.Main;
|
import org.jackhuang.hmcl.Main;
|
||||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||||
import org.jackhuang.hmcl.download.GameBuilder;
|
import org.jackhuang.hmcl.download.GameBuilder;
|
||||||
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
import org.jackhuang.hmcl.game.ModpackHelper;
|
import org.jackhuang.hmcl.game.ModpackHelper;
|
||||||
import org.jackhuang.hmcl.mod.Modpack;
|
import org.jackhuang.hmcl.mod.Modpack;
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
@@ -48,16 +49,16 @@ public final class DownloadWizardProvider implements WizardProvider {
|
|||||||
GameBuilder builder = profile.getDependency().gameBuilder();
|
GameBuilder builder = profile.getDependency().gameBuilder();
|
||||||
|
|
||||||
builder.name((String) settings.get("name"));
|
builder.name((String) settings.get("name"));
|
||||||
builder.gameVersion((String) settings.get("game"));
|
builder.gameVersion(((RemoteVersion<?>) settings.get("game")).getGameVersion());
|
||||||
|
|
||||||
if (settings.containsKey("forge"))
|
if (settings.containsKey("forge"))
|
||||||
builder.version("forge", (String) settings.get("forge"));
|
builder.version((RemoteVersion<?>) settings.get("forge"));
|
||||||
|
|
||||||
if (settings.containsKey("liteloader"))
|
if (settings.containsKey("liteloader"))
|
||||||
builder.version("liteloader", (String) settings.get("liteloader"));
|
builder.version((RemoteVersion<?>) settings.get("liteloader"));
|
||||||
|
|
||||||
if (settings.containsKey("optifine"))
|
if (settings.containsKey("optifine"))
|
||||||
builder.version("optifine", (String) settings.get("optifine"));
|
builder.version((RemoteVersion<?>) settings.get("optifine"));
|
||||||
|
|
||||||
return builder.buildAsync().finalized((a, b) -> profile.getRepository().refreshVersions());
|
return builder.buildAsync().finalized((a, b) -> profile.getRepository().refreshVersions());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ package org.jackhuang.hmcl.ui.download;
|
|||||||
import javafx.scene.Node;
|
import javafx.scene.Node;
|
||||||
import org.jackhuang.hmcl.Main;
|
import org.jackhuang.hmcl.Main;
|
||||||
import org.jackhuang.hmcl.download.BMCLAPIDownloadProvider;
|
import org.jackhuang.hmcl.download.BMCLAPIDownloadProvider;
|
||||||
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
import org.jackhuang.hmcl.game.Version;
|
import org.jackhuang.hmcl.game.Version;
|
||||||
import org.jackhuang.hmcl.setting.Profile;
|
import org.jackhuang.hmcl.setting.Profile;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
@@ -85,13 +86,13 @@ public final class InstallerWizardProvider implements WizardProvider {
|
|||||||
Task ret = Task.empty();
|
Task ret = Task.empty();
|
||||||
|
|
||||||
if (settings.containsKey("forge"))
|
if (settings.containsKey("forge"))
|
||||||
ret = ret.then(profile.getDependency().installLibraryAsync(gameVersion, version, "forge", (String) settings.get("forge")));
|
ret = ret.then(profile.getDependency().installLibraryAsync(version, (RemoteVersion<?>) settings.get("forge")));
|
||||||
|
|
||||||
if (settings.containsKey("liteloader"))
|
if (settings.containsKey("liteloader"))
|
||||||
ret = ret.then(profile.getDependency().installLibraryAsync(gameVersion, version, "liteloader", (String) settings.get("liteloader")));
|
ret = ret.then(profile.getDependency().installLibraryAsync(version, (RemoteVersion<?>) settings.get("liteloader")));
|
||||||
|
|
||||||
if (settings.containsKey("optifine"))
|
if (settings.containsKey("optifine"))
|
||||||
ret = ret.then(profile.getDependency().installLibraryAsync(gameVersion, version, "optifine", (String) settings.get("optifine")));
|
ret = ret.then(profile.getDependency().installLibraryAsync(version, (RemoteVersion<?>) settings.get("optifine")));
|
||||||
|
|
||||||
return ret.then(profile.getRepository().refreshVersionsAsync());
|
return ret.then(profile.getRepository().refreshVersionsAsync());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import javafx.scene.layout.StackPane;
|
|||||||
import javafx.scene.layout.VBox;
|
import javafx.scene.layout.VBox;
|
||||||
import org.jackhuang.hmcl.Main;
|
import org.jackhuang.hmcl.Main;
|
||||||
import org.jackhuang.hmcl.download.DownloadProvider;
|
import org.jackhuang.hmcl.download.DownloadProvider;
|
||||||
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
import org.jackhuang.hmcl.game.GameRepository;
|
import org.jackhuang.hmcl.game.GameRepository;
|
||||||
import org.jackhuang.hmcl.ui.FXUtils;
|
import org.jackhuang.hmcl.ui.FXUtils;
|
||||||
import org.jackhuang.hmcl.ui.construct.Validator;
|
import org.jackhuang.hmcl.ui.construct.Validator;
|
||||||
@@ -33,6 +34,7 @@ import org.jackhuang.hmcl.ui.wizard.WizardPage;
|
|||||||
import org.jackhuang.hmcl.util.StringUtils;
|
import org.jackhuang.hmcl.util.StringUtils;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
public class InstallersPage extends StackPane implements WizardPage {
|
public class InstallersPage extends StackPane implements WizardPage {
|
||||||
private final WizardController controller;
|
private final WizardController controller;
|
||||||
@@ -76,7 +78,7 @@ public class InstallersPage extends StackPane implements WizardPage {
|
|||||||
|
|
||||||
FXUtils.loadFXML(this, "/assets/fxml/download/installers.fxml");
|
FXUtils.loadFXML(this, "/assets/fxml/download/installers.fxml");
|
||||||
|
|
||||||
String gameVersion = (String) controller.getSettings().get("game");
|
String gameVersion = ((RemoteVersion<?>) controller.getSettings().get("game")).getGameVersion();
|
||||||
Validator hasVersion = new Validator(s -> !repository.hasVersion(s) && StringUtils.isNotBlank(s));
|
Validator hasVersion = new Validator(s -> !repository.hasVersion(s) && StringUtils.isNotBlank(s));
|
||||||
hasVersion.setMessage(Main.i18n("install.new_game.already_exists"));
|
hasVersion.setMessage(Main.i18n("install.new_game.already_exists"));
|
||||||
txtName.getValidators().add(hasVersion);
|
txtName.getValidators().add(hasVersion);
|
||||||
@@ -104,21 +106,25 @@ public class InstallersPage extends StackPane implements WizardPage {
|
|||||||
return Main.i18n("install.new_game");
|
return Main.i18n("install.new_game");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getVersion(String id) {
|
||||||
|
return ((RemoteVersion<?>) controller.getSettings().get(id)).getSelfVersion();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNavigate(Map<String, Object> settings) {
|
public void onNavigate(Map<String, Object> settings) {
|
||||||
lblGameVersion.setText(Main.i18n("install.new_game.current_game_version") + ": " + controller.getSettings().get("game"));
|
lblGameVersion.setText(Main.i18n("install.new_game.current_game_version") + ": " + getVersion("game"));
|
||||||
if (controller.getSettings().containsKey("forge"))
|
if (controller.getSettings().containsKey("forge"))
|
||||||
lblForge.setText(Main.i18n("install.installer.version", Main.i18n("install.installer.forge")) + ": " + controller.getSettings().get("forge"));
|
lblForge.setText(Main.i18n("install.installer.version", Main.i18n("install.installer.forge")) + ": " + getVersion("forge"));
|
||||||
else
|
else
|
||||||
lblForge.setText(Main.i18n("install.installer.not_installed", Main.i18n("install.installer.forge")));
|
lblForge.setText(Main.i18n("install.installer.not_installed", Main.i18n("install.installer.forge")));
|
||||||
|
|
||||||
if (controller.getSettings().containsKey("liteloader"))
|
if (controller.getSettings().containsKey("liteloader"))
|
||||||
lblLiteLoader.setText(Main.i18n("install.installer.version", Main.i18n("install.installer.liteloader")) + ": " + controller.getSettings().get("liteloader"));
|
lblLiteLoader.setText(Main.i18n("install.installer.version", Main.i18n("install.installer.liteloader")) + ": " + getVersion("liteloader"));
|
||||||
else
|
else
|
||||||
lblLiteLoader.setText(Main.i18n("install.installer.not_installed", Main.i18n("install.installer.liteloader")));
|
lblLiteLoader.setText(Main.i18n("install.installer.not_installed", Main.i18n("install.installer.liteloader")));
|
||||||
|
|
||||||
if (controller.getSettings().containsKey("optifine"))
|
if (controller.getSettings().containsKey("optifine"))
|
||||||
lblOptiFine.setText(Main.i18n("install.installer.version", Main.i18n("install.installer.optifine")) + ": " + controller.getSettings().get("optifine"));
|
lblOptiFine.setText(Main.i18n("install.installer.version", Main.i18n("install.installer.optifine")) + ": " + getVersion("optifine"));
|
||||||
else
|
else
|
||||||
lblOptiFine.setText(Main.i18n("install.installer.not_installed", Main.i18n("install.installer.optifine")));
|
lblOptiFine.setText(Main.i18n("install.installer.not_installed", Main.i18n("install.installer.optifine")));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ public final class VersionsPage extends StackPane implements WizardPage, Refresh
|
|||||||
list.getSelectionModel().selectedItemProperty().addListener((a, b, newValue) -> {
|
list.getSelectionModel().selectedItemProperty().addListener((a, b, newValue) -> {
|
||||||
if (newValue == null)
|
if (newValue == null)
|
||||||
return;
|
return;
|
||||||
controller.getSettings().put(libraryId, newValue.getRemoteVersion().getSelfVersion());
|
controller.getSettings().put(libraryId, newValue.getRemoteVersion());
|
||||||
callback.run();
|
callback.run();
|
||||||
});
|
});
|
||||||
refresh();
|
refresh();
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<VBox style="-fx-padding: 8 8 0 8;">
|
<VBox style="-fx-padding: 8 8 0 8;">
|
||||||
<Label fx:id="lblVersionName" style="-fx-font-size: 15;" textAlignment="JUSTIFY" wrapText="true" />
|
<Label fx:id="lblVersionName" style="-fx-font-size: 15;" textAlignment="JUSTIFY" wrapText="true" />
|
||||||
<Label fx:id="lblGameVersion" style="-fx-font-size: 11;" textAlignment="JUSTIFY" wrapText="true" />
|
<Label fx:id="lblGameVersion" style="-fx-font-size: 11;" textAlignment="JUSTIFY" wrapText="true" />
|
||||||
<Label fx:id="lblLibraries" style="-fx-font-size: 11; -fx-text-fill: gray;" textAlignment="JUSTIFY" wrapText="true" />
|
<Label fx:id="lblLibraries" style="-fx-font-size: 10; -fx-text-fill: gray;" textAlignment="JUSTIFY" wrapText="true" />
|
||||||
</VBox>
|
</VBox>
|
||||||
</StackPane>
|
</StackPane>
|
||||||
<StackPane fx:id="body" style="-fx-background-radius: 0 0 2 2; -fx-background-color: rgb(255,255,255,0.87); -fx-padding: 8;" minHeight="40" pickOnBounds="false">
|
<StackPane fx:id="body" style="-fx-background-radius: 0 0 2 2; -fx-background-color: rgb(255,255,255,0.87); -fx-padding: 8;" minHeight="40" pickOnBounds="false">
|
||||||
|
|||||||
@@ -18,9 +18,12 @@
|
|||||||
package org.jackhuang.hmcl.download;
|
package org.jackhuang.hmcl.download;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.download.forge.ForgeInstallTask;
|
import org.jackhuang.hmcl.download.forge.ForgeInstallTask;
|
||||||
|
import org.jackhuang.hmcl.download.forge.ForgeRemoteVersion;
|
||||||
import org.jackhuang.hmcl.download.game.*;
|
import org.jackhuang.hmcl.download.game.*;
|
||||||
import org.jackhuang.hmcl.download.liteloader.LiteLoaderInstallTask;
|
import org.jackhuang.hmcl.download.liteloader.LiteLoaderInstallTask;
|
||||||
|
import org.jackhuang.hmcl.download.liteloader.LiteLoaderRemoteVersion;
|
||||||
import org.jackhuang.hmcl.download.optifine.OptiFineInstallTask;
|
import org.jackhuang.hmcl.download.optifine.OptiFineInstallTask;
|
||||||
|
import org.jackhuang.hmcl.download.optifine.OptiFineRemoteVersion;
|
||||||
import org.jackhuang.hmcl.game.DefaultGameRepository;
|
import org.jackhuang.hmcl.game.DefaultGameRepository;
|
||||||
import org.jackhuang.hmcl.game.Version;
|
import org.jackhuang.hmcl.game.Version;
|
||||||
import org.jackhuang.hmcl.task.ParallelTask;
|
import org.jackhuang.hmcl.task.ParallelTask;
|
||||||
@@ -80,25 +83,31 @@ public class DefaultDependencyManager extends AbstractDependencyManager {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Task installLibraryAsync(String gameVersion, Version version, String libraryId, String libraryVersion) {
|
public Task installLibraryAsync(String gameVersion, Version version, String libraryId, String libraryVersion) {
|
||||||
switch (libraryId) {
|
VersionList<?> versionList = getVersionList(libraryId);
|
||||||
case "forge":
|
return versionList.loadAsync(getDownloadProvider())
|
||||||
return new ForgeInstallTask(this, gameVersion, version, libraryVersion)
|
.then(variables -> installLibraryAsync(version, versionList.getVersion(gameVersion, libraryVersion)
|
||||||
.then(variables -> new LibrariesUniqueTask(variables.get("version")))
|
.orElseThrow(() -> new IllegalStateException("Remote library " + libraryId + " has no version " + libraryVersion))));
|
||||||
.then(variables -> new MaintainTask(variables.get("version")))
|
}
|
||||||
.then(variables -> new VersionJsonSaveTask(repository, variables.get("version")));
|
|
||||||
case "liteloader":
|
@Override
|
||||||
return new LiteLoaderInstallTask(this, gameVersion, version, libraryVersion)
|
public Task installLibraryAsync(Version version, RemoteVersion<?> libraryVersion) {
|
||||||
.then(variables -> new LibrariesUniqueTask(variables.get("version")))
|
if (libraryVersion instanceof ForgeRemoteVersion)
|
||||||
.then(variables -> new MaintainTask(variables.get("version")))
|
return new ForgeInstallTask(this, version, (ForgeRemoteVersion) libraryVersion)
|
||||||
.then(variables -> new VersionJsonSaveTask(repository, variables.get("version")));
|
.then(variables -> new LibrariesUniqueTask(variables.get("version")))
|
||||||
case "optifine":
|
.then(variables -> new MaintainTask(variables.get("version")))
|
||||||
return new OptiFineInstallTask(this, gameVersion, version, libraryVersion)
|
.then(variables -> new VersionJsonSaveTask(repository, variables.get("version")));
|
||||||
.then(variables -> new LibrariesUniqueTask(variables.get("version")))
|
else if (libraryVersion instanceof LiteLoaderRemoteVersion)
|
||||||
.then(variables -> new MaintainTask(variables.get("version")))
|
return new LiteLoaderInstallTask(this, version, (LiteLoaderRemoteVersion) libraryVersion)
|
||||||
.then(variables -> new VersionJsonSaveTask(repository, variables.get("version")));
|
.then(variables -> new LibrariesUniqueTask(variables.get("version")))
|
||||||
default:
|
.then(variables -> new MaintainTask(variables.get("version")))
|
||||||
throw new IllegalArgumentException("Library id " + libraryId + " is unrecognized.");
|
.then(variables -> new VersionJsonSaveTask(repository, variables.get("version")));
|
||||||
}
|
else if (libraryVersion instanceof OptiFineRemoteVersion)
|
||||||
|
return new OptiFineInstallTask(this, version, (OptiFineRemoteVersion) libraryVersion)
|
||||||
|
.then(variables -> new LibrariesUniqueTask(variables.get("version")))
|
||||||
|
.then(variables -> new MaintainTask(variables.get("version")))
|
||||||
|
.then(variables -> new VersionJsonSaveTask(repository, variables.get("version")));
|
||||||
|
else
|
||||||
|
throw new IllegalArgumentException("Remote library " + libraryVersion + " is unrecognized.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,10 @@ public class DefaultGameBuilder extends GameBuilder {
|
|||||||
result = result.then(libraryTaskHelper(gameVersion, "liteloader"));
|
result = result.then(libraryTaskHelper(gameVersion, "liteloader"));
|
||||||
if (toolVersions.containsKey("optifine"))
|
if (toolVersions.containsKey("optifine"))
|
||||||
result = result.then(libraryTaskHelper(gameVersion, "optifine"));
|
result = result.then(libraryTaskHelper(gameVersion, "optifine"));
|
||||||
|
|
||||||
|
for (RemoteVersion<?> remoteVersion : remoteVersions)
|
||||||
|
result = result.then(var -> dependencyManager.installLibraryAsync(var.get("version"), remoteVersion));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}).finalized((variables, isDependentsSucceeded) -> {
|
}).finalized((variables, isDependentsSucceeded) -> {
|
||||||
if (!isDependentsSucceeded)
|
if (!isDependentsSucceeded)
|
||||||
|
|||||||
@@ -66,6 +66,16 @@ public interface DependencyManager {
|
|||||||
*/
|
*/
|
||||||
Task installLibraryAsync(String gameVersion, Version version, String libraryId, String libraryVersion);
|
Task installLibraryAsync(String gameVersion, Version version, String libraryId, String libraryVersion);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install a library to a version.
|
||||||
|
* **Note**: Installing a library may change the version.json.
|
||||||
|
*
|
||||||
|
* @param version the version.json.\
|
||||||
|
* @param libraryVersion the remote version of being installed library.
|
||||||
|
* @return the task to install the specific library.
|
||||||
|
*/
|
||||||
|
Task installLibraryAsync(Version version, RemoteVersion<?> libraryVersion);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get registered version list.
|
* Get registered version list.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -19,9 +19,7 @@ package org.jackhuang.hmcl.download;
|
|||||||
|
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The builder which provide a task to build Minecraft environment.
|
* The builder which provide a task to build Minecraft environment.
|
||||||
@@ -33,6 +31,7 @@ public abstract class GameBuilder {
|
|||||||
protected String name = "";
|
protected String name = "";
|
||||||
protected String gameVersion = "";
|
protected String gameVersion = "";
|
||||||
protected final Map<String, String> toolVersions = new HashMap<>();
|
protected final Map<String, String> toolVersions = new HashMap<>();
|
||||||
|
protected final Set<RemoteVersion<?>> remoteVersions = new HashSet<>();
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
@@ -65,6 +64,11 @@ public abstract class GameBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public GameBuilder version(RemoteVersion<?> remoteVersion) {
|
||||||
|
remoteVersions.add(remoteVersion);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the task that can build thw whole Minecraft environment
|
* @return the task that can build thw whole Minecraft environment
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.jackhuang.hmcl.download;
|
package org.jackhuang.hmcl.download;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.util.ToStringBuilder;
|
||||||
import org.jackhuang.hmcl.util.VersionNumber;
|
import org.jackhuang.hmcl.util.VersionNumber;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -74,6 +75,15 @@ public class RemoteVersion<T> implements Comparable<RemoteVersion<T>> {
|
|||||||
return selfVersion.hashCode();
|
return selfVersion.hashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return new ToStringBuilder(this)
|
||||||
|
.append("selfVersion", selfVersion)
|
||||||
|
.append("gameVersion", gameVersion)
|
||||||
|
.append("tag", tag)
|
||||||
|
.toString();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(RemoteVersion<T> o) {
|
public int compareTo(RemoteVersion<T> o) {
|
||||||
// newer versions are smaller than older versions
|
// newer versions are smaller than older versions
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.jackhuang.hmcl.task.Task;
|
|||||||
import org.jackhuang.hmcl.util.SimpleMultimap;
|
import org.jackhuang.hmcl.util.SimpleMultimap;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The remote version list.
|
* The remote version list.
|
||||||
@@ -45,15 +46,36 @@ public abstract class VersionList<T> {
|
|||||||
return !versions.isEmpty();
|
return !versions.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param downloadProvider DownloadProvider
|
* @param downloadProvider DownloadProvider
|
||||||
* @return the task to reload the remote version list.
|
* @return the task to reload the remote version list.
|
||||||
*/
|
*/
|
||||||
public abstract Task refreshAsync(DownloadProvider downloadProvider);
|
public abstract Task refreshAsync(DownloadProvider downloadProvider);
|
||||||
|
|
||||||
|
public Task loadAsync(DownloadProvider downloadProvider) {
|
||||||
|
return Task.ofThen(variables -> {
|
||||||
|
lock.readLock().lock();
|
||||||
|
boolean loaded;
|
||||||
|
|
||||||
|
try {
|
||||||
|
loaded = isLoaded();
|
||||||
|
} finally {
|
||||||
|
lock.readLock().unlock();
|
||||||
|
}
|
||||||
|
return loaded ? null : refreshAsync(downloadProvider);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private Collection<RemoteVersion<T>> getVersionsImpl(String gameVersion) {
|
private Collection<RemoteVersion<T>> getVersionsImpl(String gameVersion) {
|
||||||
Collection<RemoteVersion<T>> ans = versions.get(gameVersion);
|
lock.readLock().lock();
|
||||||
return ans.isEmpty() ? versions.values() : ans;
|
try {
|
||||||
|
Collection<RemoteVersion<T>> ans = versions.get(gameVersion);
|
||||||
|
return ans.isEmpty() ? versions.values() : ans;
|
||||||
|
} finally {
|
||||||
|
lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,10 +96,15 @@ public abstract class VersionList<T> {
|
|||||||
* @return the specific remote version, null if it is not found.
|
* @return the specific remote version, null if it is not found.
|
||||||
*/
|
*/
|
||||||
public final Optional<RemoteVersion<T>> getVersion(String gameVersion, String remoteVersion) {
|
public final Optional<RemoteVersion<T>> getVersion(String gameVersion, String remoteVersion) {
|
||||||
RemoteVersion<T> result = null;
|
lock.readLock().lock();
|
||||||
for (RemoteVersion<T> it : versions.get(gameVersion))
|
try {
|
||||||
if (remoteVersion.equals(it.getSelfVersion()))
|
RemoteVersion<T> result = null;
|
||||||
result = it;
|
for (RemoteVersion<T> it : versions.get(gameVersion))
|
||||||
return Optional.ofNullable(result);
|
if (remoteVersion.equals(it.getSelfVersion()))
|
||||||
|
result = it;
|
||||||
|
return Optional.ofNullable(result);
|
||||||
|
} finally {
|
||||||
|
lock.readLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,6 @@
|
|||||||
package org.jackhuang.hmcl.download.forge;
|
package org.jackhuang.hmcl.download.forge;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
||||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
|
||||||
import org.jackhuang.hmcl.download.VersionList;
|
|
||||||
import org.jackhuang.hmcl.download.game.GameLibrariesTask;
|
import org.jackhuang.hmcl.download.game.GameLibrariesTask;
|
||||||
import org.jackhuang.hmcl.game.Library;
|
import org.jackhuang.hmcl.game.Library;
|
||||||
import org.jackhuang.hmcl.game.SimpleVersionProvider;
|
import org.jackhuang.hmcl.game.SimpleVersionProvider;
|
||||||
@@ -47,34 +45,22 @@ import java.util.zip.ZipFile;
|
|||||||
public final class ForgeInstallTask extends TaskResult<Version> {
|
public final class ForgeInstallTask extends TaskResult<Version> {
|
||||||
|
|
||||||
private final DefaultDependencyManager dependencyManager;
|
private final DefaultDependencyManager dependencyManager;
|
||||||
private final String gameVersion;
|
|
||||||
private final Version version;
|
private final Version version;
|
||||||
private final String remoteVersion;
|
|
||||||
private final VersionList<?> forgeVersionList;
|
|
||||||
private final File installer = new File("forge-installer.jar").getAbsoluteFile();
|
private final File installer = new File("forge-installer.jar").getAbsoluteFile();
|
||||||
private RemoteVersion<?> remote;
|
private ForgeRemoteVersion remote;
|
||||||
private final List<Task> dependents = new LinkedList<>();
|
private final List<Task> dependents = new LinkedList<>();
|
||||||
private final List<Task> dependencies = new LinkedList<>();
|
private final List<Task> dependencies = new LinkedList<>();
|
||||||
|
|
||||||
private Task downloadFileTask() {
|
private Task downloadFileTask() {
|
||||||
remote = forgeVersionList.getVersion(gameVersion, remoteVersion)
|
|
||||||
.orElseThrow(() -> new IllegalArgumentException("Remote forge version " + gameVersion + ", " + remoteVersion + " not found"));
|
|
||||||
return new FileDownloadTask(NetworkUtils.toURL(remote.getUrl()), installer);
|
return new FileDownloadTask(NetworkUtils.toURL(remote.getUrl()), installer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ForgeInstallTask(DefaultDependencyManager dependencyManager, String gameVersion, Version version, String remoteVersion) {
|
public ForgeInstallTask(DefaultDependencyManager dependencyManager, Version version, ForgeRemoteVersion remoteVersion) {
|
||||||
this.dependencyManager = dependencyManager;
|
this.dependencyManager = dependencyManager;
|
||||||
this.gameVersion = gameVersion;
|
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.remoteVersion = remoteVersion;
|
this.remote = remoteVersion;
|
||||||
|
|
||||||
forgeVersionList = dependencyManager.getVersionList("forge");
|
dependents.add(downloadFileTask());
|
||||||
|
|
||||||
if (!forgeVersionList.isLoaded())
|
|
||||||
dependents.add(forgeVersionList.refreshAsync(dependencyManager.getDownloadProvider())
|
|
||||||
.then(s -> downloadFileTask()));
|
|
||||||
else
|
|
||||||
dependents.add(downloadFileTask());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||||
|
*/
|
||||||
|
package org.jackhuang.hmcl.download.forge;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
|
|
||||||
|
public class ForgeRemoteVersion extends RemoteVersion<Void> {
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param gameVersion the Minecraft version that this remote version suits.
|
||||||
|
* @param selfVersion the version string of the remote version.
|
||||||
|
* @param url the installer or universal jar URL.
|
||||||
|
*/
|
||||||
|
public ForgeRemoteVersion(String gameVersion, String selfVersion, String url) {
|
||||||
|
super(gameVersion, selfVersion, url, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -53,34 +53,40 @@ public final class ForgeVersionList extends VersionList<Void> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
ForgeVersionRoot root = Constants.GSON.fromJson(task.getResult(), ForgeVersionRoot.class);
|
lock.writeLock().lock();
|
||||||
if (root == null)
|
|
||||||
return;
|
|
||||||
versions.clear();
|
|
||||||
|
|
||||||
for (Map.Entry<String, int[]> entry : root.getGameVersions().entrySet()) {
|
try {
|
||||||
Optional<String> gameVersion = VersionNumber.parseVersion(entry.getKey());
|
ForgeVersionRoot root = Constants.GSON.fromJson(task.getResult(), ForgeVersionRoot.class);
|
||||||
if (!gameVersion.isPresent())
|
if (root == null)
|
||||||
continue;
|
return;
|
||||||
for (int v : entry.getValue()) {
|
versions.clear();
|
||||||
ForgeVersion version = root.getNumber().get(v);
|
|
||||||
if (version == null)
|
|
||||||
continue;
|
|
||||||
String jar = null;
|
|
||||||
for (String[] file : version.getFiles())
|
|
||||||
if (file.length > 1 && "installer".equals(file[1])) {
|
|
||||||
String classifier = version.getGameVersion() + "-" + version.getVersion()
|
|
||||||
+ (StringUtils.isNotBlank(version.getBranch()) ? "-" + version.getBranch() : "");
|
|
||||||
String fileName = root.getArtifact() + "-" + classifier + "-" + file[1] + "." + file[0];
|
|
||||||
jar = downloadProvider.injectURL(root.getWebPath() + classifier + "/" + fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (jar == null)
|
for (Map.Entry<String, int[]> entry : root.getGameVersions().entrySet()) {
|
||||||
|
Optional<String> gameVersion = VersionNumber.parseVersion(entry.getKey());
|
||||||
|
if (!gameVersion.isPresent())
|
||||||
continue;
|
continue;
|
||||||
versions.put(gameVersion.get(), new RemoteVersion<>(
|
for (int v : entry.getValue()) {
|
||||||
version.getGameVersion(), version.getVersion(), jar, null
|
ForgeVersion version = root.getNumber().get(v);
|
||||||
));
|
if (version == null)
|
||||||
|
continue;
|
||||||
|
String jar = null;
|
||||||
|
for (String[] file : version.getFiles())
|
||||||
|
if (file.length > 1 && "installer".equals(file[1])) {
|
||||||
|
String classifier = version.getGameVersion() + "-" + version.getVersion()
|
||||||
|
+ (StringUtils.isNotBlank(version.getBranch()) ? "-" + version.getBranch() : "");
|
||||||
|
String fileName = root.getArtifact() + "-" + classifier + "-" + file[1] + "." + file[0];
|
||||||
|
jar = downloadProvider.injectURL(root.getWebPath() + classifier + "/" + fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (jar == null)
|
||||||
|
continue;
|
||||||
|
versions.put(gameVersion.get(), new ForgeRemoteVersion(
|
||||||
|
version.getGameVersion(), version.getVersion(), jar
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
lock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,16 +50,22 @@ public final class GameVersionList extends VersionList<GameRemoteVersionTag> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
versions.clear();
|
lock.writeLock().lock();
|
||||||
|
|
||||||
GameRemoteVersions root = Constants.GSON.fromJson(task.getResult(), GameRemoteVersions.class);
|
try {
|
||||||
for (GameRemoteVersion remoteVersion : root.getVersions()) {
|
versions.clear();
|
||||||
versions.put(remoteVersion.getGameVersion(), new RemoteVersionGame(
|
|
||||||
remoteVersion.getGameVersion(),
|
GameRemoteVersions root = Constants.GSON.fromJson(task.getResult(), GameRemoteVersions.class);
|
||||||
remoteVersion.getGameVersion(),
|
for (GameRemoteVersion remoteVersion : root.getVersions()) {
|
||||||
remoteVersion.getUrl(),
|
versions.put(remoteVersion.getGameVersion(), new RemoteVersionGame(
|
||||||
new GameRemoteVersionTag(remoteVersion.getType(), remoteVersion.getReleaseTime()))
|
remoteVersion.getGameVersion(),
|
||||||
);
|
remoteVersion.getGameVersion(),
|
||||||
|
remoteVersion.getUrl(),
|
||||||
|
new GameRemoteVersionTag(remoteVersion.getType(), remoteVersion.getReleaseTime()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
lock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
package org.jackhuang.hmcl.download.liteloader;
|
package org.jackhuang.hmcl.download.liteloader;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
||||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
|
||||||
import org.jackhuang.hmcl.download.game.GameLibrariesTask;
|
import org.jackhuang.hmcl.download.game.GameLibrariesTask;
|
||||||
import org.jackhuang.hmcl.game.LibrariesDownloadInfo;
|
import org.jackhuang.hmcl.game.LibrariesDownloadInfo;
|
||||||
import org.jackhuang.hmcl.game.Library;
|
import org.jackhuang.hmcl.game.Library;
|
||||||
@@ -41,32 +40,15 @@ import java.util.List;
|
|||||||
public final class LiteLoaderInstallTask extends TaskResult<Version> {
|
public final class LiteLoaderInstallTask extends TaskResult<Version> {
|
||||||
|
|
||||||
private final DefaultDependencyManager dependencyManager;
|
private final DefaultDependencyManager dependencyManager;
|
||||||
private final String gameVersion;
|
|
||||||
private final Version version;
|
private final Version version;
|
||||||
private final String remoteVersion;
|
private LiteLoaderRemoteVersion remote;
|
||||||
private final LiteLoaderVersionList liteLoaderVersionList;
|
|
||||||
private RemoteVersion<LiteLoaderRemoteVersionTag> remote;
|
|
||||||
private final List<Task> dependents = new LinkedList<>();
|
private final List<Task> dependents = new LinkedList<>();
|
||||||
private final List<Task> dependencies = new LinkedList<>();
|
private final List<Task> dependencies = new LinkedList<>();
|
||||||
|
|
||||||
private void doRemote() {
|
public LiteLoaderInstallTask(DefaultDependencyManager dependencyManager, Version version, LiteLoaderRemoteVersion remoteVersion) {
|
||||||
remote = liteLoaderVersionList.getVersion(gameVersion, remoteVersion)
|
|
||||||
.orElseThrow(() -> new IllegalArgumentException("Remote LiteLoader version " + gameVersion + ", " + remoteVersion + " not found"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public LiteLoaderInstallTask(DefaultDependencyManager dependencyManager, String gameVersion, Version version, String remoteVersion) {
|
|
||||||
this.dependencyManager = dependencyManager;
|
this.dependencyManager = dependencyManager;
|
||||||
this.gameVersion = gameVersion;
|
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.remoteVersion = remoteVersion;
|
this.remote = remoteVersion;
|
||||||
|
|
||||||
liteLoaderVersionList = (LiteLoaderVersionList) dependencyManager.getVersionList("liteloader");
|
|
||||||
|
|
||||||
if (!liteLoaderVersionList.isLoaded())
|
|
||||||
dependents.add(liteLoaderVersionList.refreshAsync(dependencyManager.getDownloadProvider())
|
|
||||||
.then(Task.of(this::doRemote)));
|
|
||||||
else
|
|
||||||
doRemote();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Hello Minecraft! Launcher.
|
||||||
|
* Copyright (C) 2017 huangyuhui <huanghongxun2008@126.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see {http://www.gnu.org/licenses/}.
|
||||||
|
*/
|
||||||
|
package org.jackhuang.hmcl.download.liteloader;
|
||||||
|
|
||||||
|
import org.jackhuang.hmcl.download.RemoteVersion;
|
||||||
|
import org.jackhuang.hmcl.game.Library;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
public class LiteLoaderRemoteVersion extends RemoteVersion<LiteLoaderRemoteVersionTag> {
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param gameVersion the Minecraft version that this remote version suits.
|
||||||
|
* @param selfVersion the version string of the remote version.
|
||||||
|
* @param url the installer or universal jar URL.
|
||||||
|
*/
|
||||||
|
LiteLoaderRemoteVersion(String gameVersion, String selfVersion, String url, String tweakClass, Collection<Library> libraries) {
|
||||||
|
super(gameVersion, selfVersion, url, new LiteLoaderRemoteVersionTag(tweakClass, libraries));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -58,17 +58,23 @@ public final class LiteLoaderVersionList extends VersionList<LiteLoaderRemoteVer
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
LiteLoaderVersionsRoot root = Constants.GSON.fromJson(task.getResult(), LiteLoaderVersionsRoot.class);
|
lock.writeLock().lock();
|
||||||
versions.clear();
|
|
||||||
|
|
||||||
for (Map.Entry<String, LiteLoaderGameVersions> entry : root.getVersions().entrySet()) {
|
try {
|
||||||
String gameVersion = entry.getKey();
|
LiteLoaderVersionsRoot root = Constants.GSON.fromJson(task.getResult(), LiteLoaderVersionsRoot.class);
|
||||||
LiteLoaderGameVersions liteLoader = entry.getValue();
|
versions.clear();
|
||||||
Optional<String> gg = VersionNumber.parseVersion(gameVersion);
|
|
||||||
if (!gg.isPresent())
|
for (Map.Entry<String, LiteLoaderGameVersions> entry : root.getVersions().entrySet()) {
|
||||||
continue;
|
String gameVersion = entry.getKey();
|
||||||
doBranch(gg.get(), gameVersion, liteLoader.getRepoitory(), liteLoader.getArtifacts(), false);
|
LiteLoaderGameVersions liteLoader = entry.getValue();
|
||||||
doBranch(gg.get(), gameVersion, liteLoader.getRepoitory(), liteLoader.getSnapshots(), true);
|
Optional<String> gg = VersionNumber.parseVersion(gameVersion);
|
||||||
|
if (!gg.isPresent())
|
||||||
|
continue;
|
||||||
|
doBranch(gg.get(), gameVersion, liteLoader.getRepoitory(), liteLoader.getArtifacts(), false);
|
||||||
|
doBranch(gg.get(), gameVersion, liteLoader.getRepoitory(), liteLoader.getSnapshots(), true);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
lock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,9 +98,9 @@ public final class LiteLoaderVersionList extends VersionList<LiteLoaderRemoteVer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
versions.put(key, new RemoteVersion<>(gameVersion,
|
versions.put(key, new LiteLoaderRemoteVersion(gameVersion,
|
||||||
version, downloadProvider.injectURL(url),
|
version, downloadProvider.injectURL(url),
|
||||||
new LiteLoaderRemoteVersionTag(v.getTweakClass(), v.getLibraries())
|
v.getTweakClass(), v.getLibraries()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ public final class OptiFineBMCLVersionList extends VersionList<Void> {
|
|||||||
if (StringUtils.isBlank(element.getGameVersion()))
|
if (StringUtils.isBlank(element.getGameVersion()))
|
||||||
continue;
|
continue;
|
||||||
VersionNumber.parseVersion(element.getGameVersion())
|
VersionNumber.parseVersion(element.getGameVersion())
|
||||||
.ifPresent(gameVersion -> versions.put(gameVersion, new RemoteVersion<>(gameVersion, version, mirror, null)));
|
.ifPresent(gameVersion -> versions.put(gameVersion, new OptiFineRemoteVersion(gameVersion, version, () -> mirror)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,8 +18,6 @@
|
|||||||
package org.jackhuang.hmcl.download.optifine;
|
package org.jackhuang.hmcl.download.optifine;
|
||||||
|
|
||||||
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
import org.jackhuang.hmcl.download.DefaultDependencyManager;
|
||||||
import org.jackhuang.hmcl.download.RemoteVersion;
|
|
||||||
import org.jackhuang.hmcl.download.VersionList;
|
|
||||||
import org.jackhuang.hmcl.download.game.GameLibrariesTask;
|
import org.jackhuang.hmcl.download.game.GameLibrariesTask;
|
||||||
import org.jackhuang.hmcl.game.*;
|
import org.jackhuang.hmcl.game.*;
|
||||||
import org.jackhuang.hmcl.task.Task;
|
import org.jackhuang.hmcl.task.Task;
|
||||||
@@ -39,32 +37,15 @@ import java.util.List;
|
|||||||
public final class OptiFineInstallTask extends TaskResult<Version> {
|
public final class OptiFineInstallTask extends TaskResult<Version> {
|
||||||
|
|
||||||
private final DefaultDependencyManager dependencyManager;
|
private final DefaultDependencyManager dependencyManager;
|
||||||
private final String gameVersion;
|
|
||||||
private final Version version;
|
private final Version version;
|
||||||
private final String remoteVersion;
|
private OptiFineRemoteVersion remote;
|
||||||
private final VersionList<?> optiFineVersionList;
|
|
||||||
private RemoteVersion<?> remote;
|
|
||||||
private final List<Task> dependents = new LinkedList<>();
|
private final List<Task> dependents = new LinkedList<>();
|
||||||
private final List<Task> dependencies = new LinkedList<>();
|
private final List<Task> dependencies = new LinkedList<>();
|
||||||
|
|
||||||
private void doRemote() {
|
public OptiFineInstallTask(DefaultDependencyManager dependencyManager, Version version, OptiFineRemoteVersion remoteVersion) {
|
||||||
remote = optiFineVersionList.getVersion(gameVersion, remoteVersion)
|
|
||||||
.orElseThrow(() -> new IllegalArgumentException("Remote OptiFine version " + gameVersion + ", " + remoteVersion + " not found"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public OptiFineInstallTask(DefaultDependencyManager dependencyManager, String gameVersion, Version version, String remoteVersion) {
|
|
||||||
this.dependencyManager = dependencyManager;
|
this.dependencyManager = dependencyManager;
|
||||||
this.gameVersion = gameVersion;
|
|
||||||
this.version = version;
|
this.version = version;
|
||||||
this.remoteVersion = remoteVersion;
|
this.remote = remoteVersion;
|
||||||
|
|
||||||
optiFineVersionList = dependencyManager.getVersionList("optifine");
|
|
||||||
|
|
||||||
if (!optiFineVersionList.isLoaded())
|
|
||||||
dependents.add(optiFineVersionList.refreshAsync(dependencyManager.getDownloadProvider())
|
|
||||||
.then(Task.of(this::doRemote)));
|
|
||||||
else
|
|
||||||
doRemote();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -89,6 +70,8 @@ public final class OptiFineInstallTask extends TaskResult<Version> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() {
|
public void execute() {
|
||||||
|
String remoteVersion = remote.getSelfVersion();
|
||||||
|
|
||||||
Library library = new Library(
|
Library library = new Library(
|
||||||
"net.optifine", "optifine", remoteVersion, null, null,
|
"net.optifine", "optifine", remoteVersion, null, null,
|
||||||
new LibrariesDownloadInfo(new LibraryDownloadInfo(
|
new LibrariesDownloadInfo(new LibraryDownloadInfo(
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ import java.util.function.Supplier;
|
|||||||
public class OptiFineRemoteVersion extends RemoteVersion<Void> {
|
public class OptiFineRemoteVersion extends RemoteVersion<Void> {
|
||||||
private final Supplier<String> url;
|
private final Supplier<String> url;
|
||||||
|
|
||||||
public OptiFineRemoteVersion(String gameVersion, String selfVersion, Supplier<String> url, Void tag) {
|
public OptiFineRemoteVersion(String gameVersion, String selfVersion, Supplier<String> url) {
|
||||||
super(gameVersion, selfVersion, "", tag);
|
super(gameVersion, selfVersion, "", null);
|
||||||
|
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,48 +61,54 @@ public final class OptiFineVersionList extends VersionList<Void> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws Exception {
|
public void execute() throws Exception {
|
||||||
versions.clear();
|
lock.writeLock().lock();
|
||||||
|
|
||||||
String html = task.getResult().replace(" ", " ").replace(">", ">").replace("<", "<").replace("<br>", "<br />");
|
try {
|
||||||
|
versions.clear();
|
||||||
|
|
||||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
String html = task.getResult().replace(" ", " ").replace(">", ">").replace("<", "<").replace("<br>", "<br />");
|
||||||
DocumentBuilder db = factory.newDocumentBuilder();
|
|
||||||
Document doc = db.parse(new ByteArrayInputStream(html.getBytes("UTF-8")));
|
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||||
Element r = doc.getDocumentElement();
|
DocumentBuilder db = factory.newDocumentBuilder();
|
||||||
NodeList tables = r.getElementsByTagName("table");
|
Document doc = db.parse(new ByteArrayInputStream(html.getBytes("UTF-8")));
|
||||||
for (int i = 0; i < tables.getLength(); i++) {
|
Element r = doc.getDocumentElement();
|
||||||
Element e = (Element) tables.item(i);
|
NodeList tables = r.getElementsByTagName("table");
|
||||||
if ("downloadTable".equals(e.getAttribute("class"))) {
|
for (int i = 0; i < tables.getLength(); i++) {
|
||||||
NodeList tr = e.getElementsByTagName("tr");
|
Element e = (Element) tables.item(i);
|
||||||
for (int k = 0; k < tr.getLength(); k++) {
|
if ("downloadTable".equals(e.getAttribute("class"))) {
|
||||||
NodeList downloadLine = ((Element) tr.item(k)).getElementsByTagName("td");
|
NodeList tr = e.getElementsByTagName("tr");
|
||||||
String url = null, version = null, gameVersion = null;
|
for (int k = 0; k < tr.getLength(); k++) {
|
||||||
for (int j = 0; j < downloadLine.getLength(); j++) {
|
NodeList downloadLine = ((Element) tr.item(k)).getElementsByTagName("td");
|
||||||
Element td = (Element) downloadLine.item(j);
|
String url = null, version = null, gameVersion = null;
|
||||||
if (td.getAttribute("class") != null && td.getAttribute("class").startsWith("downloadLineMirror"))
|
for (int j = 0; j < downloadLine.getLength(); j++) {
|
||||||
url = ((Element) td.getElementsByTagName("a").item(0)).getAttribute("href");
|
Element td = (Element) downloadLine.item(j);
|
||||||
if (td.getAttribute("class") != null && td.getAttribute("class").startsWith("downloadLineFile"))
|
if (td.getAttribute("class") != null && td.getAttribute("class").startsWith("downloadLineMirror"))
|
||||||
version = td.getTextContent();
|
url = ((Element) td.getElementsByTagName("a").item(0)).getAttribute("href");
|
||||||
|
if (td.getAttribute("class") != null && td.getAttribute("class").startsWith("downloadLineFile"))
|
||||||
|
version = td.getTextContent();
|
||||||
|
}
|
||||||
|
if (version == null || url == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Matcher matcher = PATTERN.matcher(version);
|
||||||
|
while (matcher.find())
|
||||||
|
gameVersion = matcher.group(1);
|
||||||
|
if (gameVersion == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
String finalURL = url;
|
||||||
|
versions.put(gameVersion, new OptiFineRemoteVersion(gameVersion, version, Lang.hideException(() -> getLink(finalURL))));
|
||||||
}
|
}
|
||||||
if (version == null || url == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
Matcher matcher = PATTERN.matcher(version);
|
|
||||||
while (matcher.find())
|
|
||||||
gameVersion = matcher.group(1);
|
|
||||||
if (gameVersion == null)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
String finalURL = url;
|
|
||||||
versions.put(gameVersion, new OptiFineRemoteVersion(gameVersion, version, Lang.hideException(() -> getLink(finalURL)), null));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
lock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String getLink(String url) throws IOException {
|
private static String getLink(String url) throws IOException {
|
||||||
String result = null;
|
String result = null;
|
||||||
String content = NetworkUtils.doGet(NetworkUtils.toURL(url));
|
String content = NetworkUtils.doGet(NetworkUtils.toURL(url));
|
||||||
Matcher m = LINK_PATTERN.matcher(content);
|
Matcher m = LINK_PATTERN.matcher(content);
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import java.util.List;
|
|||||||
final class CoupleTask<P extends Task> extends Task {
|
final class CoupleTask<P extends Task> extends Task {
|
||||||
|
|
||||||
private final boolean relyingOnDependents;
|
private final boolean relyingOnDependents;
|
||||||
private final boolean failIfDependentsFail;
|
|
||||||
private final Collection<Task> dependents;
|
private final Collection<Task> dependents;
|
||||||
private final List<Task> dependencies = new LinkedList<>();
|
private final List<Task> dependencies = new LinkedList<>();
|
||||||
private final ExceptionalFunction<AutoTypingMap<String>, Task, ?> succ;
|
private final ExceptionalFunction<AutoTypingMap<String>, Task, ?> succ;
|
||||||
@@ -45,11 +44,10 @@ final class CoupleTask<P extends Task> extends Task {
|
|||||||
* @param succ a callback that returns the task runs after pred, succ will be executed asynchronously. You can do something that relies on the result of pred.
|
* @param succ a callback that returns the task runs after pred, succ will be executed asynchronously. You can do something that relies on the result of pred.
|
||||||
* @param relyingOnDependents true if this task chain will be broken when task pred fails.
|
* @param relyingOnDependents true if this task chain will be broken when task pred fails.
|
||||||
*/
|
*/
|
||||||
public CoupleTask(P pred, ExceptionalFunction<AutoTypingMap<String>, Task, ?> succ, boolean relyingOnDependents, boolean failIfDependentsFail) {
|
public CoupleTask(P pred, ExceptionalFunction<AutoTypingMap<String>, Task, ?> succ, boolean relyingOnDependents) {
|
||||||
this.dependents = Collections.singleton(pred);
|
this.dependents = pred == null ? Collections.emptySet() : Collections.singleton(pred);
|
||||||
this.succ = succ;
|
this.succ = succ;
|
||||||
this.relyingOnDependents = relyingOnDependents;
|
this.relyingOnDependents = relyingOnDependents;
|
||||||
this.failIfDependentsFail = failIfDependentsFail;
|
|
||||||
|
|
||||||
setSignificance(TaskSignificance.MODERATE);
|
setSignificance(TaskSignificance.MODERATE);
|
||||||
setName(succ.toString());
|
setName(succ.toString());
|
||||||
@@ -61,9 +59,6 @@ final class CoupleTask<P extends Task> extends Task {
|
|||||||
Task task = succ.apply(getVariables());
|
Task task = succ.apply(getVariables());
|
||||||
if (task != null)
|
if (task != null)
|
||||||
dependencies.add(task);
|
dependencies.add(task);
|
||||||
|
|
||||||
if (failIfDependentsFail && !isDependentsSucceeded())
|
|
||||||
throw new SilentException();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ public abstract class Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final Task then(ExceptionalFunction<AutoTypingMap<String>, Task, ?> b) {
|
public final Task then(ExceptionalFunction<AutoTypingMap<String>, Task, ?> b) {
|
||||||
return new CoupleTask<>(this, b, true, false);
|
return new CoupleTask<>(this, b, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Task with(Task b) {
|
public final Task with(Task b) {
|
||||||
@@ -252,7 +252,7 @@ public abstract class Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final <E extends Exception> Task with(ExceptionalFunction<AutoTypingMap<String>, Task, E> b) {
|
public final <E extends Exception> Task with(ExceptionalFunction<AutoTypingMap<String>, Task, E> b) {
|
||||||
return new CoupleTask<>(this, b, false, false);
|
return new CoupleTask<>(this, b, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Task finalized(FinalizedCallback b) {
|
public final Task finalized(FinalizedCallback b) {
|
||||||
@@ -312,6 +312,10 @@ public abstract class Task {
|
|||||||
return of(ReflectionHelper.getCaller().toString(), scheduler, closure);
|
return of(ReflectionHelper.getCaller().toString(), scheduler, closure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Task ofThen(ExceptionalFunction<AutoTypingMap<String>, Task, ?> b) {
|
||||||
|
return new CoupleTask<>(null, b, true);
|
||||||
|
}
|
||||||
|
|
||||||
public static <V> TaskResult<V> ofResult(String id, Callable<V> callable) {
|
public static <V> TaskResult<V> ofResult(String id, Callable<V> callable) {
|
||||||
return new TaskCallable<>(id, callable);
|
return new TaskCallable<>(id, callable);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user