From 8d52ba70a5f1bf450a45f4aff5d590afd3d043a3 Mon Sep 17 00:00:00 2001 From: IzzelAliz Date: Sat, 20 Jun 2020 19:25:27 +0800 Subject: [PATCH] Forge's maven repository has different directory structure. --- .../PhantomEntity_AttackPlayerGoalMixin.java | 2 +- .../forgeinstaller/FileDownloader.java | 3 ++ .../forgeinstaller/ForgeInstaller.java | 37 +++++++++++++------ .../forgeinstaller/MavenDownloader.java | 26 ++++++++++--- .../main/resources/META-INF/i18n/en_us.conf | 1 + .../main/resources/META-INF/i18n/zh_cn.conf | 1 + 6 files changed, 52 insertions(+), 18 deletions(-) diff --git a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/monster/PhantomEntity_AttackPlayerGoalMixin.java b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/monster/PhantomEntity_AttackPlayerGoalMixin.java index f9be68fa..ef232fe3 100644 --- a/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/monster/PhantomEntity_AttackPlayerGoalMixin.java +++ b/arclight-common/src/main/java/io/izzel/arclight/common/mixin/core/entity/monster/PhantomEntity_AttackPlayerGoalMixin.java @@ -15,7 +15,7 @@ public abstract class PhantomEntity_AttackPlayerGoalMixin { @Shadow(aliases = {"this$0", "field_203141_a"}, remap = false) private PhantomEntity outerThis; @SuppressWarnings("UnresolvedMixinReference") - @Inject(method = "shouldExecute", at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/monster/PhantomEntity;func_70624_b(Lnet/minecraft/entity/LivingEntity;)V")) + @Inject(method = "shouldExecute", at = @At(value = "INVOKE", remap = false, target = "Lnet/minecraft/entity/monster/PhantomEntity;func_70624_b(Lnet/minecraft/entity/LivingEntity;)V")) private void arclight$reason(CallbackInfoReturnable cir) { ((MobEntityBridge) outerThis).bridge$pushGoalTargetReason(EntityTargetEvent.TargetReason.CLOSEST_PLAYER, true); } diff --git a/forge-installer/src/main/java/io/izzel/arclight/forgeinstaller/FileDownloader.java b/forge-installer/src/main/java/io/izzel/arclight/forgeinstaller/FileDownloader.java index edebd7af..1a68d501 100644 --- a/forge-installer/src/main/java/io/izzel/arclight/forgeinstaller/FileDownloader.java +++ b/forge-installer/src/main/java/io/izzel/arclight/forgeinstaller/FileDownloader.java @@ -10,6 +10,7 @@ import java.net.HttpURLConnection; import java.net.SocketTimeoutException; import java.net.URL; import java.net.URLDecoder; +import java.nio.file.AccessDeniedException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; @@ -64,6 +65,8 @@ public class FileDownloader implements Supplier { } else { throw LocalizedException.checked("downloader.not-found", url); } + } catch (AccessDeniedException e) { + throw LocalizedException.unchecked("downloader.access-denied", e.getFile(), e); } catch (Exception e) { Unsafe.throwException(e); return null; diff --git a/forge-installer/src/main/java/io/izzel/arclight/forgeinstaller/ForgeInstaller.java b/forge-installer/src/main/java/io/izzel/arclight/forgeinstaller/ForgeInstaller.java index 8570f872..dcd93cd4 100644 --- a/forge-installer/src/main/java/io/izzel/arclight/forgeinstaller/ForgeInstaller.java +++ b/forge-installer/src/main/java/io/izzel/arclight/forgeinstaller/ForgeInstaller.java @@ -22,8 +22,10 @@ import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.AbstractMap; import java.util.ArrayList; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; @@ -56,7 +58,7 @@ public class ForgeInstaller { public static void install() throws Throwable { InputStream stream = ForgeInstaller.class.getResourceAsStream("/META-INF/installer.json"); InstallInfo installInfo = new Gson().fromJson(new InputStreamReader(stream), InstallInfo.class); - List> suppliers = checkMaven(installInfo.libraries); + List> suppliers = checkMavenNoSource(installInfo.libraries); Path path = Paths.get(String.format("forge-%s-%s.jar", installInfo.installer.minecraft, installInfo.installer.forge)); if (!suppliers.isEmpty() || !Files.exists(path)) { ArclightLocale.info("downloader.info"); @@ -68,6 +70,7 @@ public class ForgeInstaller { ArclightLocale.info("downloader.forge-install"); ProcessBuilder builder = new ProcessBuilder(); builder.command("java", "-jar", String.format("forge-%s-%s-installer.jar", installInfo.installer.minecraft, installInfo.installer.forge), "--installServer", "."); + builder.inheritIO(); Process process = builder.start(); process.waitFor(); } @@ -91,7 +94,7 @@ public class ForgeInstaller { CompletableFuture installerFuture = reportSupply(pool).apply(fd).thenAccept(path -> { try { FileSystem system = FileSystems.newFileSystem(path, null); - Map map = new HashMap<>(); + Map> map = new HashMap<>(); Path profile = system.getPath("install_profile.json"); map.putAll(profileLibraries(profile)); Path version = system.getPath("version.json"); @@ -126,8 +129,8 @@ public class ForgeInstaller { } } - private static Map profileLibraries(Path path) throws IOException { - Map ret = new HashMap<>(); + private static Map> profileLibraries(Path path) throws IOException { + Map> ret = new HashMap<>(); JsonArray array = new JsonParser().parse(Files.newBufferedReader(path)).getAsJsonObject().getAsJsonArray("libraries"); for (JsonElement element : array) { String name = element.getAsJsonObject().get("name").getAsString(); @@ -135,27 +138,37 @@ public class ForgeInstaller { String hash = artifact.get("sha1").getAsString(); String url = artifact.get("url").getAsString(); if (url == null || url.trim().isEmpty()) continue; - ret.put(name, hash); + ret.put(name, new AbstractMap.SimpleImmutableEntry<>(hash, url)); } return ret; } - private static List> checkMaven(Map map) { - List> incomplete = new ArrayList<>(); + private static List> checkMavenNoSource(Map map) { + LinkedHashMap> hashMap = new LinkedHashMap<>(map.size()); for (Map.Entry entry : map.entrySet()) { + hashMap.put(entry.getKey(), new AbstractMap.SimpleImmutableEntry<>(entry.getValue(), null)); + } + return checkMaven(hashMap); + } + + private static List> checkMaven(Map> map) { + List> incomplete = new ArrayList<>(); + for (Map.Entry> entry : map.entrySet()) { String maven = entry.getKey(); + String hash = entry.getValue().getKey(); + String url = entry.getValue().getValue(); String path = "libraries/" + Util.mavenToPath(maven); if (new File(path).exists()) { try { - String hash = Util.hash(path); - if (!hash.equals(entry.getValue())) { - incomplete.add(new MavenDownloader(MAVEN_REPO, maven, path, entry.getValue())); + String fileHash = Util.hash(path); + if (!fileHash.equals(hash)) { + incomplete.add(new MavenDownloader(MAVEN_REPO, maven, path, hash, url)); } } catch (Exception e) { - incomplete.add(new MavenDownloader(MAVEN_REPO, maven, path, entry.getValue())); + incomplete.add(new MavenDownloader(MAVEN_REPO, maven, path, hash, url)); } } else { - incomplete.add(new MavenDownloader(MAVEN_REPO, maven, path, entry.getValue())); + incomplete.add(new MavenDownloader(MAVEN_REPO, maven, path, hash, url)); } } return incomplete; diff --git a/forge-installer/src/main/java/io/izzel/arclight/forgeinstaller/MavenDownloader.java b/forge-installer/src/main/java/io/izzel/arclight/forgeinstaller/MavenDownloader.java index b7309c27..a023a643 100644 --- a/forge-installer/src/main/java/io/izzel/arclight/forgeinstaller/MavenDownloader.java +++ b/forge-installer/src/main/java/io/izzel/arclight/forgeinstaller/MavenDownloader.java @@ -5,31 +5,47 @@ import io.izzel.arclight.i18n.LocalizedException; import java.nio.file.Path; import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; import java.util.StringJoiner; +import java.util.function.Function; import java.util.function.Supplier; public class MavenDownloader implements Supplier { - private final String[] repos; + private static final Function FORGE_TO_BMCLAPI = + s -> s.replace("https://files.minecraftforge.net/maven/", "https://bmclapi2.bangbang93.com/maven/"); + + private final LinkedList urls; private final String coord; private final String target; private final String hash; public MavenDownloader(String[] repos, String coord, String target, String hash) { - this.repos = repos; + this.urls = new LinkedList<>(); this.coord = coord; this.target = target; this.hash = hash; + String path = Util.mavenToPath(coord); + for (String repo : repos) { + this.urls.add(repo + path); + } + } + + public MavenDownloader(String[] repos, String coord, String target, String hash, String sourceUrl) { + this(repos, coord, target, hash); + if (sourceUrl != null && !this.urls.contains(sourceUrl)) { + this.urls.addFirst(sourceUrl); + this.urls.addFirst(FORGE_TO_BMCLAPI.apply(sourceUrl)); + } } @Override public Path get() { - String path = Util.mavenToPath(coord); List exceptions = new ArrayList<>(); - for (String repo : repos) { + for (String url : this.urls) { try { - return new FileDownloader(repo + path, target, hash).get(); + return new FileDownloader(url, target, hash).get(); } catch (Exception e) { exceptions.add(e); } diff --git a/i18n-config/src/main/resources/META-INF/i18n/en_us.conf b/i18n-config/src/main/resources/META-INF/i18n/en_us.conf index 9d9c9525..e04d0e3b 100644 --- a/i18n-config/src/main/resources/META-INF/i18n/en_us.conf +++ b/i18n-config/src/main/resources/META-INF/i18n/en_us.conf @@ -27,6 +27,7 @@ downloader { maven-fail = "{0} failed to download: {1}" complete = "{0} complete" forge-install = "Forge installation is starting, please wait... " + access-denied = "Access denied for file {0}: {1}" } i18n { diff --git a/i18n-config/src/main/resources/META-INF/i18n/zh_cn.conf b/i18n-config/src/main/resources/META-INF/i18n/zh_cn.conf index b1e25112..cacdc9d9 100644 --- a/i18n-config/src/main/resources/META-INF/i18n/zh_cn.conf +++ b/i18n-config/src/main/resources/META-INF/i18n/zh_cn.conf @@ -27,6 +27,7 @@ downloader { maven-fail = "{0} 下载失败 {1}" complete = "{0} 下载完成" forge-install = "即将开始 Forge 安装,请等待一段时间" + access-denied = "没有对 {0} 操作的权限: {1}" } i18n {