package net.minecraft.data; import com.google.common.hash.Hashing; import com.google.common.hash.HashingOutputStream; import com.google.gson.JsonElement; import com.google.gson.stream.JsonWriter; import com.mojang.logging.LogUtils; import com.mojang.serialization.Codec; import com.mojang.serialization.DynamicOps; import com.mojang.serialization.JsonOps; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.Comparator; import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.function.Function; import java.util.function.ToIntFunction; import net.minecraft.Util; import net.minecraft.core.HolderLookup.Provider; import net.minecraft.resources.RegistryOps; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.GsonHelper; import org.slf4j.Logger; public interface DataProvider { ToIntFunction FIXED_ORDER_FIELDS = Util.make(new Object2IntOpenHashMap<>(), object2IntOpenHashMap -> { object2IntOpenHashMap.put("type", 0); object2IntOpenHashMap.put("parent", 1); object2IntOpenHashMap.defaultReturnValue(2); }); Comparator KEY_COMPARATOR = Comparator.comparingInt(FIXED_ORDER_FIELDS).thenComparing(string -> string); Logger LOGGER = LogUtils.getLogger(); CompletableFuture run(CachedOutput output); /** * Gets a name for this provider, to use in logging. */ String getName(); static CompletableFuture saveAll(CachedOutput output, Codec codec, PackOutput.PathProvider pathProvider, Map entries) { return saveAll(output, codec, pathProvider::json, (Map)entries); } static CompletableFuture saveAll(CachedOutput output, Codec codec, Function pathGetter, Map entries) { return saveAll(output, object -> codec.encodeStart(JsonOps.INSTANCE, (E)object).getOrThrow(), pathGetter, entries); } static CompletableFuture saveAll(CachedOutput output, Function serializer, Function pathGetter, Map entries) { return CompletableFuture.allOf((CompletableFuture[])entries.entrySet().stream().map(entry -> { Path path = (Path)pathGetter.apply(entry.getKey()); JsonElement jsonElement = (JsonElement)serializer.apply(entry.getValue()); return saveStable(output, jsonElement, path); }).toArray(CompletableFuture[]::new)); } static CompletableFuture saveStable(CachedOutput output, Provider registries, Codec codec, T value, Path path) { RegistryOps registryOps = registries.createSerializationContext(JsonOps.INSTANCE); return saveStable(output, registryOps, codec, value, path); } static CompletableFuture saveStable(CachedOutput output, Codec codec, T value, Path path) { return saveStable(output, JsonOps.INSTANCE, codec, value, path); } private static CompletableFuture saveStable(CachedOutput output, DynamicOps ops, Codec codec, T value, Path path) { JsonElement jsonElement = codec.encodeStart(ops, value).getOrThrow(); return saveStable(output, jsonElement, path); } static CompletableFuture saveStable(CachedOutput output, JsonElement json, Path path) { return CompletableFuture.runAsync(() -> { try { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); HashingOutputStream hashingOutputStream = new HashingOutputStream(Hashing.sha1(), byteArrayOutputStream); JsonWriter jsonWriter = new JsonWriter(new OutputStreamWriter(hashingOutputStream, StandardCharsets.UTF_8)); try { jsonWriter.setSerializeNulls(false); jsonWriter.setIndent(" "); GsonHelper.writeValue(jsonWriter, json, KEY_COMPARATOR); } catch (Throwable var9) { try { jsonWriter.close(); } catch (Throwable var8) { var9.addSuppressed(var8); } throw var9; } jsonWriter.close(); output.writeIfNeeded(path, byteArrayOutputStream.toByteArray(), hashingOutputStream.hash()); } catch (IOException var10) { LOGGER.error("Failed to save file to {}", path, var10); } }, Util.backgroundExecutor().forName("saveStable")); } @FunctionalInterface public interface Factory { T create(PackOutput packOutput); } }