Fix resource packs not being sorted properly. Closes #6287

This commit is contained in:
LexManos 2020-04-26 16:50:42 -07:00
parent 3c5728f070
commit 746d702058
4 changed files with 51 additions and 7 deletions

View File

@ -232,6 +232,7 @@ project(':forge') {
}
version = getVersion()
println('Forge Version: ' + version)
patcher {
exc = file("$rootDir/src/main/resources/forge.exc")

View File

@ -0,0 +1,11 @@
--- a/net/minecraft/resources/ResourcePackList.java
+++ b/net/minecraft/resources/ResourcePackList.java
@@ -48,7 +48,7 @@
private void func_198986_e() {
List<Entry<String, T>> list = Lists.newArrayList(this.field_198988_b.entrySet());
this.field_198988_b.clear();
- list.stream().sorted(Entry.comparingByKey()).forEachOrdered((p_198984_1_) -> {
+ list.stream().sorted(net.minecraftforge.fml.packs.ResourcePackLoader.getSorter()).forEachOrdered((p_198984_1_) -> {
ResourcePackInfo resourcepackinfo = (ResourcePackInfo)this.field_198988_b.put(p_198984_1_.getKey(), p_198984_1_.getValue());
});
}

View File

@ -19,7 +19,11 @@
package net.minecraftforge.fml.packs;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
@ -28,11 +32,9 @@ import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import net.minecraft.resources.IPackFinder;
import net.minecraft.resources.ResourcePack;
import net.minecraft.resources.ResourcePackInfo;
import net.minecraft.resources.ResourcePackList;
import net.minecraftforge.fml.ModList;
@ -55,10 +57,40 @@ public class ResourcePackLoader
modResourcePacks = ModList.get().getModFiles().stream().
filter(mf->!Objects.equals(mf.getModLoader(),"minecraft")).
map(mf -> new ModFileResourcePack(mf.getFile())).
collect(Collectors.toMap(ModFileResourcePack::getModFile, Function.identity()));
collect(Collectors.toMap(ModFileResourcePack::getModFile, Function.identity(), (u,v) -> { throw new IllegalStateException(String.format("Duplicate key %s", u)); }, LinkedHashMap::new));
resourcePacks.addPackFinder(new LambdaFriendlyPackFinder(packFinder.apply(modResourcePacks, ModFileResourcePack::setPackInfo)));
}
public static <V> Comparator<Map.Entry<String,V>> getSorter() {
List<String> order = new ArrayList<>();
order.add("vanilla");
order.add("mod_resources");
ModList.get().getModFiles().stream().
filter(mf -> !Objects.equals(mf.getModLoader(), "minecraft")).
map(e -> e.getMods().get(0).getModId()).
filter(e -> !"minecraft".equals(e)).
map(e -> "mod:" + e).
forEach(order::add);
final Object2IntMap<String> order_f = new Object2IntOpenHashMap<>(order.size());
for (int x = 0; x < order.size(); x++)
order_f.put(order.get(x), x);
return (e1, e2) -> {
final String s1 = e1.getKey();
final String s2 = e2.getKey();
final int i1 = order_f.getOrDefault(s1, -1);
final int i2 = order_f.getOrDefault(s2, -1);
if (i1 == i2 && i1 == -1)
return s1.compareTo(s2);
if (i1 == -1) return 1;
if (i2 == -1) return -1;
return i2 - i1;
};
}
public interface IPackInfoFinder<T extends ResourcePackInfo> {
void addPackInfosToMap(Map<String, T> packList, ResourcePackInfo.IFactory<T> factory);
}

View File

@ -207,7 +207,7 @@ public class ServerLifecycleHooks
IModInfo mod = e.getKey().getModInfos().get(0);
if (Objects.equals(mod.getModId(), "minecraft")) continue; // skip the minecraft "mod"
final String name = "mod:" + mod.getModId();
final T packInfo = ResourcePackInfo.createResourcePack(name, true, e::getValue, factory, ResourcePackInfo.Priority.TOP);
final T packInfo = ResourcePackInfo.createResourcePack(name, true, e::getValue, factory, ResourcePackInfo.Priority.BOTTOM);
if (packInfo == null) {
// Vanilla only logs an error, instead of propagating, so handle null and warn that something went wrong
ModLoader.get().addWarning(new ModLoadingWarning(mod, ModLoadingStage.ERROR, "fml.modloading.brokenresources", e.getKey()));