package net.minecraft.world.level.chunk.storage; import org.apache.logging.log4j.LogManager; import com.google.common.collect.ImmutableMap; import net.minecraft.SharedConstants; import java.util.Map; import com.google.common.collect.Maps; import net.minecraft.nbt.Tag; import java.io.IOException; import com.mojang.datafixers.types.DynamicOps; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtOps; import net.minecraft.world.level.Level; import net.minecraft.Util; import javax.annotation.Nullable; import net.minecraft.world.level.ChunkPos; import net.minecraft.core.SectionPos; import java.util.function.BooleanSupplier; import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import java.io.File; import net.minecraft.util.datafix.DataFixTypes; import com.mojang.datafixers.DataFixer; import java.util.function.Function; import com.mojang.datafixers.Dynamic; import java.util.function.BiFunction; import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet; import java.util.Optional; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import org.apache.logging.log4j.Logger; import net.minecraft.util.Serializable; public class SectionStorage implements AutoCloseable { private static final Logger LOGGER; private final IOWorker worker; private final Long2ObjectMap> storage; private final LongLinkedOpenHashSet dirty; private final BiFunction, R> deserializer; private final Function factory; private final DataFixer fixerUpper; private final DataFixTypes type; public SectionStorage(final File file, final BiFunction, R> biFunction, final Function function, final DataFixer dataFixer, final DataFixTypes acd) { this.storage = (Long2ObjectMap>)new Long2ObjectOpenHashMap(); this.dirty = new LongLinkedOpenHashSet(); this.deserializer = biFunction; this.factory = function; this.fixerUpper = dataFixer; this.type = acd; this.worker = new IOWorker(new RegionFileStorage(file), file.getName()); } protected void tick(final BooleanSupplier booleanSupplier) { while (!this.dirty.isEmpty() && booleanSupplier.getAsBoolean()) { final ChunkPos bje3 = SectionPos.of(this.dirty.firstLong()).chunk(); this.writeColumn(bje3); } } @Nullable protected Optional get(final long long1) { return (Optional)this.storage.get(long1); } protected Optional getOrLoad(final long long1) { final SectionPos gd4 = SectionPos.of(long1); if (this.outsideStoredRange(gd4)) { return Optional.empty(); } Optional optional5 = this.get(long1); if (optional5 != null) { return optional5; } this.readColumn(gd4.chunk()); optional5 = this.get(long1); if (optional5 == null) { throw Util.pauseInIde(new IllegalStateException()); } return optional5; } protected boolean outsideStoredRange(final SectionPos gd) { return Level.isOutsideBuildHeight(SectionPos.sectionToBlockCoord(gd.y())); } protected R getOrCreate(final long long1) { final Optional optional4 = this.getOrLoad(long1); if (optional4.isPresent()) { return optional4.get(); } final R abu5 = this.factory.apply(() -> this.setDirty(long1)); this.storage.put(long1, Optional.of(abu5)); return abu5; } private void readColumn(final ChunkPos bje) { this.readColumn(bje, (com.mojang.datafixers.types.DynamicOps)NbtOps.INSTANCE, this.tryRead(bje)); } @Nullable private CompoundTag tryRead(final ChunkPos bje) { try { return this.worker.load(bje); } catch (IOException iOException3) { SectionStorage.LOGGER.error("Error reading chunk {} data from disk", bje, iOException3); return null; } } private void readColumn(final ChunkPos bje, final DynamicOps dynamicOps, @Nullable final T object) { // // This method could not be decompiled. // // Original Bytecode: // // 1: ifnonnull 45 // 4: iconst_0 // 5: istore integer5 // 7: iload integer5 // 9: bipush 16 // 11: if_icmpge 42 // 14: aload_0 /* this */ // 15: getfield net/minecraft/world/level/chunk/storage/SectionStorage.storage:Lit/unimi/dsi/fastutil/longs/Long2ObjectMap; // 18: aload_1 /* bje */ // 19: iload integer5 // 21: invokestatic net/minecraft/core/SectionPos.of:(Lnet/minecraft/world/level/ChunkPos;I)Lnet/minecraft/core/SectionPos; // 24: invokevirtual net/minecraft/core/SectionPos.asLong:()J // 27: invokestatic java/util/Optional.empty:()Ljava/util/Optional; // 30: invokeinterface it/unimi/dsi/fastutil/longs/Long2ObjectMap.put:(JLjava/lang/Object;)Ljava/lang/Object; // 35: pop // 36: iinc integer5, 1 // 39: goto 7 // 42: goto 203 // 45: new Lcom/mojang/datafixers/Dynamic; // 48: dup // 49: aload_2 /* dynamicOps */ // 50: aload_3 /* object */ // 51: invokespecial com/mojang/datafixers/Dynamic.:(Lcom/mojang/datafixers/types/DynamicOps;Ljava/lang/Object;)V // 54: astore dynamic5 // 56: aload dynamic5 // 58: invokestatic net/minecraft/world/level/chunk/storage/SectionStorage.getVersion:(Lcom/mojang/datafixers/Dynamic;)I // 61: istore integer6 // 63: invokestatic net/minecraft/SharedConstants.getCurrentVersion:()Lcom/mojang/bridge/game/GameVersion; // 66: invokeinterface com/mojang/bridge/game/GameVersion.getWorldVersion:()I // 71: istore integer7 // 73: iload integer6 // 75: iload integer7 // 77: if_icmpeq 84 // 80: iconst_1 // 81: goto 85 // 84: iconst_0 // 85: istore boolean8 // 87: aload_0 /* this */ // 88: getfield net/minecraft/world/level/chunk/storage/SectionStorage.fixerUpper:Lcom/mojang/datafixers/DataFixer; // 91: aload_0 /* this */ // 92: getfield net/minecraft/world/level/chunk/storage/SectionStorage.type:Lnet/minecraft/util/datafix/DataFixTypes; // 95: invokevirtual net/minecraft/util/datafix/DataFixTypes.getType:()Lcom/mojang/datafixers/DSL$TypeReference; // 98: aload dynamic5 // 100: iload integer6 // 102: iload integer7 // 104: invokeinterface com/mojang/datafixers/DataFixer.update:(Lcom/mojang/datafixers/DSL$TypeReference;Lcom/mojang/datafixers/Dynamic;II)Lcom/mojang/datafixers/Dynamic; // 109: astore dynamic9 // 111: aload dynamic9 // 113: ldc_w "Sections" // 116: invokevirtual com/mojang/datafixers/Dynamic.get:(Ljava/lang/String;)Lcom/mojang/datafixers/OptionalDynamic; // 119: astore optionalDynamic10 // 121: iconst_0 // 122: istore integer11 // 124: iload integer11 // 126: bipush 16 // 128: if_icmpge 203 // 131: aload_1 /* bje */ // 132: iload integer11 // 134: invokestatic net/minecraft/core/SectionPos.of:(Lnet/minecraft/world/level/ChunkPos;I)Lnet/minecraft/core/SectionPos; // 137: invokevirtual net/minecraft/core/SectionPos.asLong:()J // 140: lstore long12 // 142: aload optionalDynamic10 // 144: iload integer11 // 146: invokestatic java/lang/Integer.toString:(I)Ljava/lang/String; // 149: invokevirtual com/mojang/datafixers/OptionalDynamic.get:(Ljava/lang/String;)Lcom/mojang/datafixers/OptionalDynamic; // 152: invokevirtual com/mojang/datafixers/OptionalDynamic.get:()Ljava/util/Optional; // 155: aload_0 /* this */ // 156: lload long12 // 158: invokedynamic BootstrapMethod #1, apply:(Lnet/minecraft/world/level/chunk/storage/SectionStorage;J)Ljava/util/function/Function; // 163: invokevirtual java/util/Optional.map:(Ljava/util/function/Function;)Ljava/util/Optional; // 166: astore optional14 // 168: aload_0 /* this */ // 169: getfield net/minecraft/world/level/chunk/storage/SectionStorage.storage:Lit/unimi/dsi/fastutil/longs/Long2ObjectMap; // 172: lload long12 // 174: aload optional14 // 176: invokeinterface it/unimi/dsi/fastutil/longs/Long2ObjectMap.put:(JLjava/lang/Object;)Ljava/lang/Object; // 181: pop // 182: aload optional14 // 184: aload_0 /* this */ // 185: lload long12 // 187: iload boolean8 // 189: invokedynamic BootstrapMethod #2, accept:(Lnet/minecraft/world/level/chunk/storage/SectionStorage;JZ)Ljava/util/function/Consumer; // 194: invokevirtual java/util/Optional.ifPresent:(Ljava/util/function/Consumer;)V // 197: iinc integer11, 1 // 200: goto 124 // 203: return // Signature: // (Lnet/minecraft/world/level/ChunkPos;Lcom/mojang/datafixers/types/DynamicOps;TT;)V // MethodParameters: // Name Flags // ---------- ----- // bje // dynamicOps // object // StackMapTable: 00 07 FF 00 07 00 05 07 00 02 07 00 F5 00 00 01 00 00 FF 00 22 00 00 00 00 FF 00 02 00 04 07 00 02 07 00 F5 07 01 0C 07 00 05 00 00 FF 00 26 00 07 07 00 02 07 00 F5 00 00 07 01 0E 01 01 00 00 40 01 FF 00 26 00 0B 07 00 02 07 00 F5 00 00 00 00 00 01 00 07 01 33 01 00 00 FF 00 4E 00 00 00 00 // // The error that occurred was: // // java.lang.NullPointerException // at com.strobel.decompiler.languages.java.ast.NameVariables.generateNameForVariable(NameVariables.java:264) // at com.strobel.decompiler.languages.java.ast.NameVariables.assignNamesToVariables(NameVariables.java:198) // at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:276) // at com.strobel.decompiler.languages.java.ast.AstMethodBodyBuilder.createMethodBody(AstMethodBodyBuilder.java:99) // at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethodBody(AstBuilder.java:782) // at com.strobel.decompiler.languages.java.ast.AstBuilder.createMethod(AstBuilder.java:675) // at com.strobel.decompiler.languages.java.ast.AstBuilder.addTypeMembers(AstBuilder.java:552) // at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeCore(AstBuilder.java:519) // at com.strobel.decompiler.languages.java.ast.AstBuilder.createTypeNoCache(AstBuilder.java:161) // at com.strobel.decompiler.languages.java.ast.AstBuilder.createType(AstBuilder.java:150) // at com.strobel.decompiler.languages.java.ast.AstBuilder.addType(AstBuilder.java:125) // at cuchaz.enigma.SourceProvider.getSources(SourceProvider.java:85) // at cuchaz.enigma.EnigmaProject$JarExport.decompileClass(EnigmaProject.java:241) // at cuchaz.enigma.EnigmaProject$JarExport.lambda$decompile$1(EnigmaProject.java:230) // at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195) // at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1654) // at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484) // at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474) // at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:952) // at java.base/java.util.stream.ReduceOps$ReduceTask.doLeaf(ReduceOps.java:926) // at java.base/java.util.stream.AbstractTask.compute(AbstractTask.java:327) // at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746) // at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290) // at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.helpCC(ForkJoinPool.java:1115) // at java.base/java.util.concurrent.ForkJoinPool.externalHelpComplete(ForkJoinPool.java:1957) // at java.base/java.util.concurrent.ForkJoinTask.tryExternalHelp(ForkJoinTask.java:378) // at java.base/java.util.concurrent.ForkJoinTask.externalAwaitDone(ForkJoinTask.java:323) // at java.base/java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:412) // at java.base/java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:736) // at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateParallel(ReduceOps.java:919) // at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233) // at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578) // at cuchaz.enigma.EnigmaProject$JarExport.decompile(EnigmaProject.java:233) // at cuchaz.enigma.command.DecompileCommand.run(DecompileCommand.java:35) // at cuchaz.enigma.CommandMain.main(CommandMain.java:43) // throw new IllegalStateException("An error occurred while decompiling this method."); } private void writeColumn(final ChunkPos bje) { final Dynamic dynamic3 = this.writeColumn(bje, (com.mojang.datafixers.types.DynamicOps)NbtOps.INSTANCE); final Tag kj4 = (Tag)dynamic3.getValue(); if (kj4 instanceof CompoundTag) { this.worker.store(bje, (CompoundTag)kj4); } else { SectionStorage.LOGGER.error("Expected compound tag, got {}", kj4); } } private Dynamic writeColumn(final ChunkPos bje, final DynamicOps dynamicOps) { final Map map4 = Maps.newHashMap(); for (int integer5 = 0; integer5 < 16; ++integer5) { final long long6 = SectionPos.of(bje, integer5).asLong(); this.dirty.remove(long6); final Optional optional8 = (Optional)this.storage.get(long6); if (optional8 != null) { if (optional8.isPresent()) { map4.put((T)dynamicOps.createString(Integer.toString(integer5)), optional8.get().serialize(dynamicOps)); } } } return (Dynamic)new Dynamic((DynamicOps)dynamicOps, dynamicOps.createMap((Map)ImmutableMap.of(dynamicOps.createString("Sections"), dynamicOps.createMap((Map)map4), dynamicOps.createString("DataVersion"), dynamicOps.createInt(SharedConstants.getCurrentVersion().getWorldVersion())))); } protected void onSectionLoad(final long long1) { } protected void setDirty(final long long1) { final Optional optional4 = (Optional)this.storage.get(long1); if (optional4 == null || !optional4.isPresent()) { SectionStorage.LOGGER.warn("No data for position: {}", SectionPos.of(long1)); return; } this.dirty.add(long1); } private static int getVersion(final Dynamic dynamic) { return dynamic.get("DataVersion").asNumber().orElse(1945).intValue(); } public void flush(final ChunkPos bje) { if (!this.dirty.isEmpty()) { for (int integer3 = 0; integer3 < 16; ++integer3) { final long long4 = SectionPos.of(bje, integer3).asLong(); if (this.dirty.contains(long4)) { this.writeColumn(bje); return; } } } } @Override public void close() throws IOException { this.worker.close(); } static { LOGGER = LogManager.getLogger(); } }