Add blockstate compression optimization (off by default for mod compat)

This commit is contained in:
embeddedt 2023-04-08 22:15:32 -04:00
parent 9ab6bc83b8
commit a2af0cf835
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
6 changed files with 171 additions and 2 deletions

View File

@ -1,7 +1,9 @@
package org.embeddedt.modernfix.core;
import com.google.common.collect.ImmutableList;
import com.google.common.io.Resources;
import cpw.mods.modlauncher.*;
import cpw.mods.modlauncher.api.INameMappingService;
import cpw.mods.modlauncher.api.LamdbaExceptionUtils;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;
import net.minecraftforge.fml.loading.LoadingModList;
@ -11,6 +13,7 @@ import org.embeddedt.modernfix.classloading.ModernFixResourceFinder;
import org.embeddedt.modernfix.core.config.ModernFixEarlyConfig;
import org.embeddedt.modernfix.core.config.Option;
import org.embeddedt.modernfix.util.DummyList;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.*;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
@ -26,6 +29,8 @@ import java.net.URL;
import java.net.URLClassLoader;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class ModernFixMixinPlugin implements IMixinConfigPlugin {
private static final String MIXIN_PACKAGE_ROOT = "org.embeddedt.modernfix.mixin.";
@ -212,6 +217,40 @@ public class ModernFixMixinPlugin implements IMixinConfigPlugin {
@Override
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
if(mixinClassName.equals("org.embeddedt.modernfix.mixin.perf.compress_blockstate.BlockStateBaseMixin")) {
// Delete unused fields off BlockStateBase
Set<String> fieldsToDelete = Stream.of(
"field_235702_f_", // isAir
"field_235703_g_", // material
"field_235705_i_", // destroySpeed
"field_235706_j_", // requiresCorrectToolForDrops
"field_235707_k_", // canOcclude
"field_235708_l_", // isRedstoneConductor
"field_235709_m_", // isSuffocating
"field_235710_n_", // isViewBlocking
"field_235711_o_", // hasPostProcess
"field_235712_p_" // emissiveRendering
).map(name -> ObfuscationReflectionHelper.remapName(INameMappingService.Domain.FIELD, name)).collect(Collectors.toSet());
targetClass.fields.removeIf(field -> {
if(fieldsToDelete.contains(field.name)) {
logger.info("Removing " + field.name);
return true;
}
return false;
});
for(MethodNode m : targetClass.methods) {
if(m.name.equals("<init>")) {
ListIterator<AbstractInsnNode> iter = m.instructions.iterator();
while(iter.hasNext()) {
AbstractInsnNode node = iter.next();
if(node.getOpcode() == Opcodes.PUTFIELD) {
if(fieldsToDelete.contains(((FieldInsnNode)node).name)) {
iter.remove();
}
}
}
}
}
}
}
}

View File

@ -43,6 +43,7 @@ public class ModernFixEarlyConfig {
this.addMixinRule("perf.cache_strongholds", true);
this.addMixinRule("perf.cache_upgraded_structures", true);
this.addMixinRule("perf.biome_zoomer", true);
this.addMixinRule("perf.compress_blockstate", false);
this.addMixinRule("bugfix.concurrency", true);
this.addMixinRule("bugfix.edge_chunk_not_saved", true);
this.addMixinRule("bugfix.packet_leak", false);

View File

@ -0,0 +1,14 @@
package org.embeddedt.modernfix.mixin.perf.compress_blockstate;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Overwrite;
@Mixin(BlockBehaviour.class)
public class BlockBehaviourMixin {
@Overwrite
protected boolean isAir(BlockState state) {
return state.getBlock().properties.isAir;
}
}

View File

@ -0,0 +1,102 @@
package org.embeddedt.modernfix.mixin.perf.compress_blockstate;
import com.google.common.collect.ImmutableMap;
import com.mojang.serialization.MapCodec;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockBehaviour;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateHolder;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.material.Material;
import org.objectweb.asm.Opcodes;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(BlockBehaviour.BlockStateBase.class)
public abstract class BlockStateBaseMixin extends StateHolder<Block, BlockState> {
protected BlockStateBaseMixin(Block object, ImmutableMap<Property<?>, Comparable<?>> immutableMap, MapCodec<BlockState> mapCodec) {
super(object, immutableMap, mapCodec);
}
@Redirect(method = "*", at = @At(
value = "FIELD",
opcode = Opcodes.GETFIELD,
target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;material:Lnet/minecraft/world/level/material/Material;"
))
private Material getMaterial(BlockBehaviour.BlockStateBase base) {
return this.owner.properties.material;
}
@Redirect(method = "*", at = @At(
value = "FIELD",
opcode = Opcodes.GETFIELD,
target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;destroySpeed:F"
))
private float getDestroyTime(BlockBehaviour.BlockStateBase base) {
return this.owner.properties.destroyTime;
}
@Redirect(method = "*", at = @At(
value = "FIELD",
opcode = Opcodes.GETFIELD,
target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;requiresCorrectToolForDrops:Z"
))
private boolean getRequiresTool(BlockBehaviour.BlockStateBase base) {
return this.owner.properties.requiresCorrectToolForDrops;
}
@Redirect(method = "*", at = @At(
value = "FIELD",
opcode = Opcodes.GETFIELD,
target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;canOcclude:Z"
))
private boolean getCanOcclude(BlockBehaviour.BlockStateBase base) {
return this.owner.properties.canOcclude;
}
@Redirect(method = "*", at = @At(
value = "FIELD",
opcode = Opcodes.GETFIELD,
target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;isRedstoneConductor:Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate;"
))
private BlockBehaviour.StatePredicate getRedstoneConductor(BlockBehaviour.BlockStateBase base) {
return this.owner.properties.isRedstoneConductor;
}
@Redirect(method = "*", at = @At(
value = "FIELD",
opcode = Opcodes.GETFIELD,
target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;isSuffocating:Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate;"
))
private BlockBehaviour.StatePredicate getSuffocating(BlockBehaviour.BlockStateBase base) {
return this.owner.properties.isSuffocating;
}
@Redirect(method = "*", at = @At(
value = "FIELD",
opcode = Opcodes.GETFIELD,
target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;isViewBlocking:Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate;"
))
private BlockBehaviour.StatePredicate getViewBlocking(BlockBehaviour.BlockStateBase base) {
return this.owner.properties.isViewBlocking;
}
@Redirect(method = "*", at = @At(
value = "FIELD",
opcode = Opcodes.GETFIELD,
target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;hasPostProcess:Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate;"
))
private BlockBehaviour.StatePredicate getPostProcess(BlockBehaviour.BlockStateBase base) {
return this.owner.properties.hasPostProcess;
}
@Redirect(method = "*", at = @At(
value = "FIELD",
opcode = Opcodes.GETFIELD,
target = "Lnet/minecraft/world/level/block/state/BlockBehaviour$BlockStateBase;emissiveRendering:Lnet/minecraft/world/level/block/state/BlockBehaviour$StatePredicate;"
))
private BlockBehaviour.StatePredicate getEmissiveRendering(BlockBehaviour.BlockStateBase base) {
return this.owner.properties.emissiveRendering;
}
}

View File

@ -11,4 +11,15 @@ public net.minecraft.server.MinecraftServer field_211151_aa # nextTickTime
public net.minecraft.client.Minecraft field_213277_ad # progressListener
public-f net.minecraft.network.datasync.DataParameter field_187157_a # id
public-f net.minecraft.network.datasync.EntityDataManager field_187234_c # itemsById
public-f net.minecraft.network.datasync.EntityDataManager field_187235_d # lock
public-f net.minecraft.network.datasync.EntityDataManager field_187235_d # lock
public net.minecraft.block.AbstractBlock field_235684_aB_ # properties
public net.minecraft.block.AbstractBlock$Properties field_200953_a # material
public net.minecraft.block.AbstractBlock$Properties field_226895_m_ # canOcclude
public net.minecraft.block.AbstractBlock$Properties field_235813_o_ # isAir
public net.minecraft.block.AbstractBlock$Properties field_235815_q_ # isRedstoneConductor
public net.minecraft.block.AbstractBlock$Properties field_235816_r_ # isSuffocating
public net.minecraft.block.AbstractBlock$Properties field_235817_s_ # isViewBlocking
public net.minecraft.block.AbstractBlock$Properties field_235818_t_ # hasPostProcess
public net.minecraft.block.AbstractBlock$Properties field_235819_u_ # emissiveRendering
public net.minecraft.block.AbstractBlock$Properties field_235806_h_ # requiresCorrectToolForDrops
public net.minecraft.block.AbstractBlock$Properties field_200959_g # destroyTime

View File

@ -62,6 +62,8 @@
"perf.cache_strongholds.ServerLevelMixin",
"perf.state_definition_construct.StateDefinitionMixin",
"perf.biome_zoomer.FuzzyOffsetBiomeZoomerMixin",
"perf.compress_blockstate.BlockStateBaseMixin",
"perf.compress_blockstate.BlockBehaviourMixin",
"devenv.MinecraftServerMixin"
],
"client": [