Merge remote-tracking branch 'origin/1.19.2' into 1.19.4
This commit is contained in:
commit
144bdaa301
|
|
@ -1,33 +0,0 @@
|
|||
package org.embeddedt.modernfix.common.mixin.bugfix.edge_chunk_not_saved;
|
||||
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.chunk.ProtoChunk;
|
||||
import net.minecraft.world.level.chunk.ImposterProtoChunk;
|
||||
import net.minecraft.world.level.chunk.ChunkAccess;
|
||||
import net.minecraft.server.level.ChunkHolder;
|
||||
import net.minecraft.server.level.ChunkMap;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/* https://github.com/SuperCoder7979/chunksavingfix-fabric/blob/main/src/main/java/supercoder79/chunksavingfix/mixin/MixinThreadedAnvilChunkStorage.java */
|
||||
@Mixin(ChunkMap.class)
|
||||
public class ChunkManagerMixin {
|
||||
// TODO: hits both at the moment- check and re-evaluate
|
||||
@ModifyArg(method = "saveAllChunks(Z)V", at = @At(value = "INVOKE", target = "Ljava/util/stream/Stream;filter(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;", ordinal = 0), require = 0)
|
||||
private Predicate<ChunkHolder> alwaysAccessibleFlush(Predicate<ChunkHolder> chunkHolder) {
|
||||
return c -> true;
|
||||
}
|
||||
@ModifyArg(method = "saveAllChunks(Z)V", at = @At(value = "INVOKE", target = "Ljava/util/stream/Stream;filter(Ljava/util/function/Predicate;)Ljava/util/stream/Stream;", ordinal = 1), require = 0)
|
||||
private Predicate<ChunkAccess> allowProtoChunkFlush(Predicate<ChunkAccess> chunk) {
|
||||
return c -> c instanceof ProtoChunk || c instanceof ImposterProtoChunk || c instanceof LevelChunk;
|
||||
}
|
||||
|
||||
@Redirect(method = "saveChunkIfNeeded", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/level/ChunkHolder;wasAccessibleSinceLastSave()Z"), require = 0)
|
||||
private boolean alwaysAccessible(ChunkHolder chunkHolder) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,55 +2,34 @@ package org.embeddedt.modernfix.common.mixin.perf.faster_item_rendering;
|
|||
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.VertexConsumer;
|
||||
import net.minecraft.client.color.item.ItemColors;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.ItemTransform;
|
||||
import net.minecraft.client.renderer.entity.ItemRenderer;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.client.resources.model.SimpleBakedModel;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.item.ItemDisplayContext;
|
||||
import net.minecraft.world.item.BlockItem;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.embeddedt.modernfix.render.FastItemRenderType;
|
||||
import org.embeddedt.modernfix.render.RenderState;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.embeddedt.modernfix.render.SimpleItemModelView;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.ModifyVariable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(ItemRenderer.class)
|
||||
@Mixin(value = ItemRenderer.class, priority = 600)
|
||||
public abstract class ItemRendererMixin {
|
||||
@Shadow @Final private ItemColors itemColors;
|
||||
|
||||
private final RandomSource dummyRandom = RandomSource.createNewThreadLocalInstance();
|
||||
|
||||
private static final float[] COLOR_MULTIPLIER = new float[]{1.0F, 1.0F, 1.0F, 1.0F};
|
||||
|
||||
private ItemDisplayContext transformType;
|
||||
private final SimpleItemModelView modelView = new SimpleItemModelView();
|
||||
|
||||
@Inject(method = "render", at = @At("HEAD"))
|
||||
private void markRenderingType(ItemStack itemStack, ItemDisplayContext transformType, boolean leftHand, PoseStack matrixStack, MultiBufferSource buffer, int combinedLight, int combinedOverlay, BakedModel model, CallbackInfo ci) {
|
||||
this.transformType = transformType;
|
||||
}
|
||||
|
||||
private static final Direction[] ITEM_DIRECTIONS = new Direction[] { Direction.SOUTH };
|
||||
private static final Direction[] BLOCK_DIRECTIONS = new Direction[] { Direction.UP, Direction.EAST, Direction.NORTH };
|
||||
|
||||
private boolean isCorrectDirectionForType(FastItemRenderType type, Direction direction) {
|
||||
if(type == FastItemRenderType.SIMPLE_ITEM)
|
||||
return direction == Direction.SOUTH;
|
||||
else {
|
||||
return direction == Direction.UP || direction == Direction.EAST || direction == Direction.NORTH;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a model
|
||||
* - is a vanilla item model (SimpleBakedModel),
|
||||
|
|
@ -59,8 +38,8 @@ public abstract class ItemRendererMixin {
|
|||
* we do not need to go through the process of rendering every quad. Just render the south ones (the ones facing the
|
||||
* camera).
|
||||
*/
|
||||
@Inject(method = "renderModelLists", at = @At("HEAD"), cancellable = true)
|
||||
private void fasterItemRender(BakedModel model, ItemStack stack, int combinedLight, int combinedOverlay, PoseStack matrixStack, VertexConsumer buffer, CallbackInfo ci) {
|
||||
@ModifyVariable(method = "renderModelLists", at = @At("HEAD"), index = 1, argsOnly = true)
|
||||
private BakedModel useSimpleWrappedItemModel(BakedModel model, BakedModel arg, ItemStack stack, int combinedLight, int combinedOverlay, PoseStack matrixStack, VertexConsumer buffer) {
|
||||
if(!RenderState.IS_RENDERING_LEVEL && !stack.isEmpty() && model.getClass() == SimpleBakedModel.class && transformType == ItemDisplayContext.GUI) {
|
||||
FastItemRenderType type;
|
||||
ItemTransform transform = model.getTransforms().gui;
|
||||
|
|
@ -69,26 +48,12 @@ public abstract class ItemRendererMixin {
|
|||
else if(stack.getItem() instanceof BlockItem && isBlockTransforms(transform))
|
||||
type = FastItemRenderType.SIMPLE_BLOCK;
|
||||
else
|
||||
return;
|
||||
ci.cancel();
|
||||
PoseStack.Pose pose = matrixStack.last();
|
||||
int[] combinedLights = new int[] {combinedLight, combinedLight, combinedLight, combinedLight};
|
||||
Direction[] directions = type == FastItemRenderType.SIMPLE_ITEM ? ITEM_DIRECTIONS : BLOCK_DIRECTIONS;
|
||||
for(Direction direction : directions) {
|
||||
List<BakedQuad> culledFaces = model.getQuads(null, direction, dummyRandom);
|
||||
/* check size to avoid instantiating iterator when the list is empty */
|
||||
if(culledFaces.size() > 0) {
|
||||
for(BakedQuad quad : culledFaces) {
|
||||
render2dItemFace(quad, stack, buffer, pose, combinedLights, combinedOverlay);
|
||||
}
|
||||
}
|
||||
}
|
||||
List<BakedQuad> unculledFaces = model.getQuads(null, null, dummyRandom);
|
||||
for(BakedQuad quad : unculledFaces) {
|
||||
if(isCorrectDirectionForType(type, quad.getDirection()))
|
||||
render2dItemFace(quad, stack, buffer, pose, combinedLights, combinedOverlay);
|
||||
}
|
||||
}
|
||||
return model;
|
||||
modelView.setItem(model);
|
||||
modelView.setType(type);
|
||||
return modelView;
|
||||
} else
|
||||
return model;
|
||||
}
|
||||
|
||||
private boolean isBlockTransforms(ItemTransform transform) {
|
||||
|
|
@ -96,16 +61,4 @@ public abstract class ItemRendererMixin {
|
|||
&& transform.rotation.y() == 225f
|
||||
&& transform.rotation.z() == 0f;
|
||||
}
|
||||
|
||||
private void render2dItemFace(BakedQuad quad, ItemStack stack, VertexConsumer buffer, PoseStack.Pose pose, int[] combinedLights, int combinedOverlay) {
|
||||
int i = -1;
|
||||
if (quad.isTinted()) {
|
||||
i = this.itemColors.getColor(stack, quad.getTintIndex());
|
||||
}
|
||||
|
||||
float f = (float)(i >> 16 & 255) / 255.0F;
|
||||
float f1 = (float)(i >> 8 & 255) / 255.0F;
|
||||
float f2 = (float)(i & 255) / 255.0F;
|
||||
buffer.putBulkData(pose, quad, COLOR_MULTIPLIER, f, f1, f2, combinedLights, combinedOverlay, true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,6 +59,8 @@ public class ModernFixEarlyConfig {
|
|||
private final Set<String> mixinOptions = new ObjectOpenHashSet<>();
|
||||
private final Map<String, String> mixinsMissingMods = new Object2ObjectOpenHashMap<>();
|
||||
|
||||
public static boolean isFabric = false;
|
||||
|
||||
public Map<String, String> getPermanentlyDisabledMixins() {
|
||||
return mixinsMissingMods;
|
||||
}
|
||||
|
|
@ -71,6 +73,8 @@ public class ModernFixEarlyConfig {
|
|||
if(stream == null)
|
||||
continue;
|
||||
try(Reader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8))) {
|
||||
if(configFile.contains("fabric"))
|
||||
isFabric = true;
|
||||
JsonObject configObject = (JsonObject)new JsonParser().parse(reader);
|
||||
JsonArray mixinList = configObject.getAsJsonArray("mixins");
|
||||
String packageName = configObject.get("package").getAsString().replace('.', '/');
|
||||
|
|
@ -178,15 +182,20 @@ public class ModernFixEarlyConfig {
|
|||
disableIfModPresent("mixin.perf.thread_priorities", "smoothboot");
|
||||
disableIfModPresent("mixin.perf.boost_worker_count", "smoothboot");
|
||||
disableIfModPresent("mixin.perf.async_jei", "modernui");
|
||||
disableIfModPresent("mixin.perf.compress_biome_container", "chocolate", "betterendforge");
|
||||
disableIfModPresent("mixin.perf.compress_biome_container", "chocolate", "betterendforge" ,"skyblockbuilder");
|
||||
disableIfModPresent("mixin.bugfix.mc218112", "performant");
|
||||
disableIfModPresent("mixin.bugfix.remove_block_chunkloading", "performant");
|
||||
disableIfModPresent("mixin.bugfix.paper_chunk_patches", "c2me");
|
||||
// DimThread makes changes to the server chunk manager (understandably), C2ME probably does the same
|
||||
disableIfModPresent("mixin.bugfix.chunk_deadlock", "c2me", "dimthread");
|
||||
disableIfModPresent("mixin.perf.reuse_datapacks", "tac");
|
||||
disableIfModPresent("mixin.launch.class_search_cache", "optifine");
|
||||
disableIfModPresent("mixin.perf.faster_texture_stitching", "optifine");
|
||||
disableIfModPresent("mixin.perf.datapack_reload_exceptions", "cyanide");
|
||||
disableIfModPresent("mixin.perf.faster_texture_loading", "stitch", "optifine", "changed");
|
||||
if(isFabric) {
|
||||
disableIfModPresent("mixin.bugfix.packet_leak", "memoryleakfix");
|
||||
}
|
||||
}
|
||||
|
||||
private void disableIfModPresent(String configName, String... ids) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,94 @@
|
|||
package org.embeddedt.modernfix.render;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.ItemOverrides;
|
||||
import net.minecraft.client.renderer.block.model.ItemTransforms;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.model.BakedModel;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.util.RandomSource;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Wrapper class that presents a fake view of item models (only showing the simple front-facing quads), rather
|
||||
* than every quad.
|
||||
*/
|
||||
public class SimpleItemModelView implements BakedModel {
|
||||
private BakedModel wrappedItem;
|
||||
private FastItemRenderType type;
|
||||
|
||||
public void setItem(BakedModel model) {
|
||||
this.wrappedItem = model;
|
||||
}
|
||||
|
||||
public void setType(FastItemRenderType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
private boolean isCorrectDirectionForType(Direction direction) {
|
||||
if(type == FastItemRenderType.SIMPLE_ITEM)
|
||||
return direction == Direction.SOUTH;
|
||||
else {
|
||||
return direction == Direction.UP || direction == Direction.EAST || direction == Direction.NORTH;
|
||||
}
|
||||
}
|
||||
|
||||
private final List<BakedQuad> nullQuadList = new ObjectArrayList<>();
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, RandomSource rand) {
|
||||
if(side != null) {
|
||||
return isCorrectDirectionForType(side) ? wrappedItem.getQuads(state, side, rand) : ImmutableList.of();
|
||||
} else {
|
||||
nullQuadList.clear();
|
||||
List<BakedQuad> realList = wrappedItem.getQuads(state, null, rand);
|
||||
for(int i = 0; i < realList.size(); i++) {
|
||||
BakedQuad quad = realList.get(i);
|
||||
if(isCorrectDirectionForType(quad.getDirection())) {
|
||||
nullQuadList.add(quad);
|
||||
}
|
||||
}
|
||||
return nullQuadList;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean useAmbientOcclusion() {
|
||||
return wrappedItem.useAmbientOcclusion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d() {
|
||||
return wrappedItem.isGui3d();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesBlockLight() {
|
||||
return wrappedItem.usesBlockLight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCustomRenderer() {
|
||||
return wrappedItem.isCustomRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite getParticleIcon() {
|
||||
return wrappedItem.getParticleIcon();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemTransforms getTransforms() {
|
||||
return wrappedItem.getTransforms();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemOverrides getOverrides() {
|
||||
return wrappedItem.getOverrides();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,22 +1,28 @@
|
|||
package org.embeddedt.modernfix.searchtree;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import me.shedaniel.rei.api.client.registry.entry.EntryRegistry;
|
||||
import me.shedaniel.rei.api.common.entry.EntryStack;
|
||||
import me.shedaniel.rei.api.common.entry.type.VanillaEntryTypes;
|
||||
import me.shedaniel.rei.impl.client.search.AsyncSearchManager;
|
||||
import me.shedaniel.rei.impl.common.entry.type.EntryRegistryImpl;
|
||||
import me.shedaniel.rei.impl.common.util.HashedEntryStackWrapper;
|
||||
import net.minecraft.client.searchtree.RefreshableSearchTree;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import org.embeddedt.modernfix.ModernFix;
|
||||
import org.embeddedt.modernfix.platform.ModernFixPlatformHooks;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
public class REIBackedSearchTree extends DummySearchTree<ItemStack> {
|
||||
private final AsyncSearchManager searchManager = new AsyncSearchManager(EntryRegistry.getInstance()::getPreFilteredList, () -> {
|
||||
return stack -> true;
|
||||
}, EntryStack::normalize);
|
||||
private final AsyncSearchManager searchManager = createSearchManager();
|
||||
|
||||
private final boolean filteringByTag;
|
||||
private String lastSearchText = "";
|
||||
|
|
@ -39,14 +45,23 @@ public class REIBackedSearchTree extends DummySearchTree<ItemStack> {
|
|||
if(!pSearchText.equals(lastSearchText)) {
|
||||
listCache.clear();
|
||||
this.searchManager.updateFilter(pSearchText);
|
||||
List<EntryStack<?>> stacks;
|
||||
List stacks;
|
||||
try {
|
||||
stacks = this.searchManager.getNow();
|
||||
} catch(RuntimeException e) {
|
||||
ModernFix.LOGGER.error("Couldn't search for '" + pSearchText + "'", e);
|
||||
stacks = Collections.emptyList();
|
||||
}
|
||||
for(EntryStack<?> stack : stacks) {
|
||||
for(Object o : stacks) {
|
||||
EntryStack<?> stack;
|
||||
if(o instanceof EntryStack<?>)
|
||||
stack = (EntryStack<?>)o;
|
||||
else if(o instanceof HashedEntryStackWrapper) {
|
||||
stack = ((HashedEntryStackWrapper)o).unwrap();
|
||||
} else {
|
||||
ModernFix.LOGGER.error("Don't know how to handle {}", o.getClass().getName());
|
||||
continue;
|
||||
}
|
||||
if(stack.getType() == VanillaEntryTypes.ITEM) {
|
||||
listCache.add(stack.cheatsAs().getValue());
|
||||
}
|
||||
|
|
@ -56,6 +71,50 @@ public class REIBackedSearchTree extends DummySearchTree<ItemStack> {
|
|||
return listCache;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
private static AsyncSearchManager createSearchManager() {
|
||||
Method m, normalizeMethod;
|
||||
try {
|
||||
try {
|
||||
m = EntryRegistryImpl.class.getDeclaredMethod("getPreFilteredComplexList");
|
||||
m.setAccessible(true);
|
||||
normalizeMethod = HashedEntryStackWrapper.class.getDeclaredMethod("normalize");
|
||||
normalizeMethod.setAccessible(true);
|
||||
} catch(NoSuchMethodException e) {
|
||||
m = EntryRegistryImpl.class.getDeclaredMethod("getPreFilteredList");
|
||||
m.setAccessible(true);
|
||||
normalizeMethod = EntryStack.class.getDeclaredMethod("normalize");
|
||||
normalizeMethod.setAccessible(true);
|
||||
}
|
||||
final MethodHandle getListMethod = MethodHandles.publicLookup().unreflect(m);
|
||||
final MethodHandle normalize = MethodHandles.publicLookup().unreflect(normalizeMethod);
|
||||
final EntryRegistryImpl registry = (EntryRegistryImpl)EntryRegistry.getInstance();
|
||||
Supplier stackListSupplier = () -> {
|
||||
try {
|
||||
return (List)getListMethod.invokeExact(registry);
|
||||
} catch(Throwable e) {
|
||||
if(e instanceof RuntimeException)
|
||||
throw (RuntimeException)e;
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
UnaryOperator normalizeOperator = o -> {
|
||||
try {
|
||||
return normalize.invoke(o);
|
||||
} catch(Throwable e) {
|
||||
if(e instanceof RuntimeException)
|
||||
throw (RuntimeException)e;
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
};
|
||||
return new AsyncSearchManager(stackListSupplier, () -> {
|
||||
return Predicates.alwaysTrue();
|
||||
}, normalizeOperator);
|
||||
} catch(ReflectiveOperationException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static final SearchTreeProviderRegistry.Provider PROVIDER = new SearchTreeProviderRegistry.Provider() {
|
||||
@Override
|
||||
public RefreshableSearchTree<ItemStack> getSearchTree(boolean tag) {
|
||||
|
|
|
|||
|
|
@ -141,6 +141,7 @@ public class CanonizingStringMap<T> implements Map<String, T> {
|
|||
}
|
||||
|
||||
public static <T> CanonizingStringMap<T> deepCopy(CanonizingStringMap<T> inputMap, Function<T, T> deepCopier) {
|
||||
Objects.requireNonNull(deepCopier);
|
||||
Object2ObjectMap<String, T> copiedBackingMap;
|
||||
int size = inputMap.backingMap.size();
|
||||
if(size > GROWTH_THRESHOLD) {
|
||||
|
|
@ -148,7 +149,8 @@ public class CanonizingStringMap<T> implements Map<String, T> {
|
|||
} else
|
||||
copiedBackingMap = new Object2ObjectArrayMap<>(size);
|
||||
inputMap.backingMap.object2ObjectEntrySet().forEach(entry -> {
|
||||
copiedBackingMap.put(entry.getKey(), deepCopier.apply(entry.getValue()));
|
||||
if(entry.getKey() != null && entry.getValue() != null)
|
||||
copiedBackingMap.put(entry.getKey(), deepCopier.apply(entry.getValue()));
|
||||
});
|
||||
return new CanonizingStringMap<>(copiedBackingMap);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user