2025-11-24 22:52:51 +03:00

129 lines
5.6 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* com.mojang.datafixers.DSL
* com.mojang.datafixers.DataFix
* com.mojang.datafixers.DataFixUtils
* com.mojang.datafixers.OpticFinder
* com.mojang.datafixers.TypeRewriteRule
* com.mojang.datafixers.Typed
* com.mojang.datafixers.schemas.Schema
* com.mojang.datafixers.types.Type
* com.mojang.datafixers.types.templates.List$ListType
* com.mojang.datafixers.util.Pair
* com.mojang.serialization.Dynamic
*/
package net.minecraft.util.datafix.fixes;
import com.mojang.datafixers.DSL;
import com.mojang.datafixers.DataFix;
import com.mojang.datafixers.DataFixUtils;
import com.mojang.datafixers.OpticFinder;
import com.mojang.datafixers.TypeRewriteRule;
import com.mojang.datafixers.Typed;
import com.mojang.datafixers.schemas.Schema;
import com.mojang.datafixers.types.Type;
import com.mojang.datafixers.types.templates.List;
import com.mojang.datafixers.util.Pair;
import com.mojang.serialization.Dynamic;
import java.util.List;
import java.util.stream.LongStream;
import net.minecraft.util.Mth;
import net.minecraft.util.datafix.fixes.References;
public class BitStorageAlignFix
extends DataFix {
private static final int BIT_TO_LONG_SHIFT = 6;
private static final int SECTION_WIDTH = 16;
private static final int SECTION_HEIGHT = 16;
private static final int SECTION_SIZE = 4096;
private static final int HEIGHTMAP_BITS = 9;
private static final int HEIGHTMAP_SIZE = 256;
public BitStorageAlignFix(Schema schema) {
super(schema, false);
}
protected TypeRewriteRule makeRule() {
Type chunkType = this.getInputSchema().getType(References.CHUNK);
Type levelType = chunkType.findFieldType("Level");
OpticFinder levelFinder = DSL.fieldFinder((String)"Level", (Type)levelType);
OpticFinder sectionsFinder = levelFinder.type().findField("Sections");
Type sectionType = ((List.ListType)sectionsFinder.type()).getElement();
OpticFinder sectionFinder = DSL.typeFinder((Type)sectionType);
Type blockStateType = DSL.named((String)References.BLOCK_STATE.typeName(), (Type)DSL.remainderType());
OpticFinder paletteFinder = DSL.fieldFinder((String)"Palette", (Type)DSL.list((Type)blockStateType));
return this.fixTypeEverywhereTyped("BitStorageAlignFix", chunkType, this.getOutputSchema().getType(References.CHUNK), chunk -> chunk.updateTyped(levelFinder, level -> this.updateHeightmaps(BitStorageAlignFix.updateSections(sectionsFinder, sectionFinder, paletteFinder, level))));
}
private Typed<?> updateHeightmaps(Typed<?> level) {
return level.update(DSL.remainderFinder(), tag -> tag.update("Heightmaps", heightmaps -> heightmaps.updateMapValues(e -> e.mapSecond(heightmap -> BitStorageAlignFix.updateBitStorage(tag, heightmap, 256, 9)))));
}
private static Typed<?> updateSections(OpticFinder<?> sectionsFinder, OpticFinder<?> sectionFinder, OpticFinder<List<Pair<String, Dynamic<?>>>> paletteFinder, Typed<?> level) {
return level.updateTyped(sectionsFinder, sections -> sections.updateTyped(sectionFinder, section -> {
int bits = section.getOptional(paletteFinder).map(palette -> Math.max(4, DataFixUtils.ceillog2((int)palette.size()))).orElse(0);
if (bits == 0 || Mth.isPowerOfTwo(bits)) {
return section;
}
return section.update(DSL.remainderFinder(), tag -> tag.update("BlockStates", states -> BitStorageAlignFix.updateBitStorage(tag, states, 4096, bits)));
}));
}
private static Dynamic<?> updateBitStorage(Dynamic<?> tag, Dynamic<?> storage, int size, int bits) {
long[] input = storage.asLongStream().toArray();
long[] output = BitStorageAlignFix.addPadding(size, bits, input);
return tag.createLongList(LongStream.of(output));
}
public static long[] addPadding(int size, int bits, long[] data) {
int dataLength = data.length;
if (dataLength == 0) {
return data;
}
long mask = (1L << bits) - 1L;
int valuesPerLong = 64 / bits;
int requiredLength = (size + valuesPerLong - 1) / valuesPerLong;
long[] result = new long[requiredLength];
int outputDataIndex = 0;
int outputStart = 0;
long outputData = 0L;
int currentIndex = 0;
long current = data[0];
long next = dataLength > 1 ? data[1] : 0L;
for (int index = 0; index < size; ++index) {
long valueToInsert;
int position = index * bits;
int startData = position >> 6;
int endData = (index + 1) * bits - 1 >> 6;
int startBit = position ^ startData << 6;
if (startData != currentIndex) {
current = next;
next = startData + 1 < dataLength ? data[startData + 1] : 0L;
currentIndex = startData;
}
if (startData == endData) {
valueToInsert = current >>> startBit & mask;
} else {
int shiftBits = 64 - startBit;
valueToInsert = (current >>> startBit | next << shiftBits) & mask;
}
int outputEnd = outputStart + bits;
if (outputEnd >= 64) {
result[outputDataIndex++] = outputData;
outputData = valueToInsert;
outputStart = bits;
continue;
}
outputData |= valueToInsert << outputStart;
outputStart = outputEnd;
}
if (outputData != 0L) {
result[outputDataIndex] = outputData;
}
return result;
}
}