diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/ArclightConnector_1_16.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/ArclightConnector_1_16.java index 5729e105..877d6e8c 100644 --- a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/ArclightConnector_1_16.java +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/ArclightConnector_1_16.java @@ -14,6 +14,9 @@ public class ArclightConnector_1_16 extends ArclightConnector { if (ArclightConfig.spec().getOptimization().isRemoveStream()) { Mixins.addConfiguration("mixins.arclight.impl.optimization.stream.1_16.json"); } + if (ArclightConfig.spec().getOptimization().isDisableDFU()) { + Mixins.addConfiguration("mixins.arclight.impl.optimization.dfu.1_16.json"); + } LOGGER.info("mixin-load.optimization"); } } diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/CraftMagicNumbersMixin.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/CraftMagicNumbersMixin.java new file mode 100644 index 00000000..68cc156e --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/CraftMagicNumbersMixin.java @@ -0,0 +1,21 @@ +package io.izzel.arclight.impl.mixin.optimization.dfu; + +import io.izzel.arclight.i18n.ArclightLocale; +import org.bukkit.craftbukkit.v.util.CraftMagicNumbers; +import org.bukkit.plugin.InvalidPluginException; +import org.bukkit.plugin.PluginDescriptionFile; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(value = CraftMagicNumbers.class, remap = false) +public class CraftMagicNumbersMixin { + + @Inject(method = "checkSupported", at = @At("HEAD")) + private void arclight$dfuDisabled(PluginDescriptionFile pdf, CallbackInfo ci) throws InvalidPluginException { + if (pdf.getAPIVersion() == null) { + throw new InvalidPluginException(ArclightLocale.getInstance().get("dfu-disable.legacy-plugin")); + } + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/DataFixerUpperMixin.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/DataFixerUpperMixin.java new file mode 100644 index 00000000..4b43844d --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/DataFixerUpperMixin.java @@ -0,0 +1,20 @@ +package io.izzel.arclight.impl.mixin.optimization.dfu; + +import com.mojang.datafixers.DSL; +import com.mojang.datafixers.DataFixerUpper; +import com.mojang.serialization.Dynamic; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +@Mixin(value = DataFixerUpper.class, remap = false) +public abstract class DataFixerUpperMixin { + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + public Dynamic update(DSL.TypeReference type, Dynamic input, int version, int newVersion) { + return input; + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/DataFixesManagerMixin.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/DataFixesManagerMixin.java new file mode 100644 index 00000000..41462fd8 --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/DataFixesManagerMixin.java @@ -0,0 +1,19 @@ +package io.izzel.arclight.impl.mixin.optimization.dfu; + +import com.mojang.datafixers.DataFixer; +import com.mojang.datafixers.DataFixerBuilder; +import net.minecraft.util.SharedConstants; +import net.minecraft.util.datafix.DataFixesManager; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(DataFixesManager.class) +public class DataFixesManagerMixin { + + @Inject(method = "createFixer", cancellable = true, at = @At("HEAD")) + private static void arclight$disableDfu(CallbackInfoReturnable cir) { + cir.setReturnValue(new DataFixerBuilder(SharedConstants.getVersion().getWorldVersion()).build(r -> {})); + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/EntityType_BuilderMixin.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/EntityType_BuilderMixin.java new file mode 100644 index 00000000..b4446485 --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/EntityType_BuilderMixin.java @@ -0,0 +1,46 @@ +package io.izzel.arclight.impl.mixin.optimization.dfu; + +import com.google.common.collect.ImmutableSet; +import net.minecraft.block.Block; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityClassification; +import net.minecraft.entity.EntitySize; +import net.minecraft.entity.EntityType; +import net.minecraft.world.World; +import net.minecraftforge.fml.network.FMLPlayMessages; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.Shadow; + +import java.util.function.BiFunction; +import java.util.function.Predicate; +import java.util.function.ToIntFunction; + +@Mixin(EntityType.Builder.class) +public class EntityType_BuilderMixin { + + @Shadow private boolean serializable; + @Shadow @Final private EntityType.IFactory factory; + @Shadow @Final private EntityClassification classification; + @Shadow private boolean summonable; + @Shadow private boolean immuneToFire; + @Shadow private boolean field_225436_f; + @Shadow private EntitySize size; + @Shadow private Predicate> velocityUpdateSupplier; + @Shadow private ToIntFunction> trackingRangeSupplier; + @Shadow private ToIntFunction> updateIntervalSupplier; + @Shadow private BiFunction customClientFactory; + @Shadow private int field_233605_i_; + @Shadow private int trackingRange; + @Shadow private ImmutableSet field_233603_c_; + + /** + * @author Izzel_Aliz + * @reason + */ + @Overwrite + public EntityType build(String id) { + return new EntityType<>(this.factory, this.classification, this.serializable, this.summonable, this.immuneToFire, this.field_225436_f, this.field_233603_c_, this.size, this.trackingRange, this.field_233605_i_, velocityUpdateSupplier, trackingRangeSupplier, updateIntervalSupplier, customClientFactory); + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/MinecraftServerMixin.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/MinecraftServerMixin.java new file mode 100644 index 00000000..33dafc0e --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/MinecraftServerMixin.java @@ -0,0 +1,21 @@ +package io.izzel.arclight.impl.mixin.optimization.dfu; + +import io.izzel.arclight.i18n.ArclightLocale; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.storage.SaveFormat; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(MinecraftServer.class) +public abstract class MinecraftServerMixin { + + @Inject(method = "func_240777_a_", cancellable = true, at = @At("HEAD")) + private static void arclight$skipConvert(SaveFormat.LevelSave levelSave, CallbackInfo ci) { + if (levelSave.isSaveFormatOutdated()) { + throw new RuntimeException(ArclightLocale.getInstance().get("dfu-disable.map-convert")); + } + ci.cancel(); + } +} diff --git a/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/TileEntityTypeMixin.java b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/TileEntityTypeMixin.java new file mode 100644 index 00000000..a9173816 --- /dev/null +++ b/arclight-forge-1.16/src/main/java/io/izzel/arclight/impl/mixin/optimization/dfu/TileEntityTypeMixin.java @@ -0,0 +1,20 @@ +package io.izzel.arclight.impl.mixin.optimization.dfu; + +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityType; +import net.minecraft.util.registry.Registry; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; + +@Mixin(TileEntityType.class) +public class TileEntityTypeMixin { + + /** + * @author IzzelAliz + * @reason + */ + @Overwrite + private static TileEntityType register(String key, TileEntityType.Builder builder) { + return Registry.register(Registry.BLOCK_ENTITY_TYPE, key, builder.build(null)); + } +} diff --git a/arclight-forge-1.16/src/main/resources/mixins.arclight.impl.optimization.dfu.1_16.json b/arclight-forge-1.16/src/main/resources/mixins.arclight.impl.optimization.dfu.1_16.json new file mode 100644 index 00000000..1ff6605b --- /dev/null +++ b/arclight-forge-1.16/src/main/resources/mixins.arclight.impl.optimization.dfu.1_16.json @@ -0,0 +1,14 @@ +{ + "minVersion": "0.8", + "package": "io.izzel.arclight.impl.mixin.optimization.dfu", + "target": "@env(DEFAULT)", + "refmap": "mixins.arclight.impl.refmap.1_15.json", + "mixins": [ + "CraftMagicNumbersMixin", + "DataFixerUpperMixin", + "DataFixesManagerMixin", + "EntityType_BuilderMixin", + "MinecraftServerMixin", + "TileEntityTypeMixin" + ] +} \ No newline at end of file diff --git a/i18n-config/src/main/java/io/izzel/arclight/i18n/conf/OptimizationSpec.java b/i18n-config/src/main/java/io/izzel/arclight/i18n/conf/OptimizationSpec.java index 60595ca7..400749d5 100644 --- a/i18n-config/src/main/java/io/izzel/arclight/i18n/conf/OptimizationSpec.java +++ b/i18n-config/src/main/java/io/izzel/arclight/i18n/conf/OptimizationSpec.java @@ -12,6 +12,9 @@ public class OptimizationSpec { @Setting("cache-plugin-class") private boolean cachePluginClass; + @Setting("disable-data-fixer") + private boolean disableDFU; + public boolean isRemoveStream() { return removeStream; } @@ -19,4 +22,8 @@ public class OptimizationSpec { public boolean isCachePluginClass() { return cachePluginClass; } + + public boolean isDisableDFU() { + return disableDFU; + } } diff --git a/i18n-config/src/main/resources/META-INF/arclight.conf b/i18n-config/src/main/resources/META-INF/arclight.conf index 9f55a453..f44aa9ec 100644 --- a/i18n-config/src/main/resources/META-INF/arclight.conf +++ b/i18n-config/src/main/resources/META-INF/arclight.conf @@ -6,6 +6,7 @@ locale { optimization { remove-stream = true cache-plugin-class = true + disable-data-fixer = false } compatibility { material-property-overrides { diff --git a/i18n-config/src/main/resources/META-INF/i18n/en_us.conf b/i18n-config/src/main/resources/META-INF/i18n/en_us.conf index d2d1059d..9f29be87 100644 --- a/i18n-config/src/main/resources/META-INF/i18n/en_us.conf +++ b/i18n-config/src/main/resources/META-INF/i18n/en_us.conf @@ -74,6 +74,10 @@ registry { error = "{} prodived entityClass {} is invalid: {}" } } +dfu-disable { + legacy-plugin = "Legacy plugin is not allowed when optimization.disable-data-fixer is enabled" + map-convert = "World upgrading is not allowed when optimization.disable-data-fixer is enabled" +} comments { _v.comment = [ @@ -84,7 +88,15 @@ comments { "Config version number, do not edit." ] locale.comment = "Language/I18n settings" - optimization.comment = "Optimization related settings" + optimization { + comment = "Optimization related settings" + disable-data-fixer.comment = [ + "Disable the DataFixerUpper system which is used for level data upgrading" + "This can hopefully speedup startup and world load and reduce memory usage of 80-200mb" + "Arclight and its developers are not reponsible for any data loss or corruption" + "DO NOT USE IN PRODUCTION!" + ] + } async-catcher.comment = [ "Async Catcher related settings" "There are four modes, and BLOCK is recommended" diff --git a/i18n-config/src/main/resources/META-INF/i18n/zh_cn.conf b/i18n-config/src/main/resources/META-INF/i18n/zh_cn.conf index 3eab5484..a08e48a8 100644 --- a/i18n-config/src/main/resources/META-INF/i18n/zh_cn.conf +++ b/i18n-config/src/main/resources/META-INF/i18n/zh_cn.conf @@ -74,6 +74,10 @@ registry { error = "{} 提供的 entityClass {} 无效: {}" } } +dfu-disable { + legacy-plugin = "Legacy 插件在 optimization.disable-data-fixer 启用时不可用" + map-convert = "地图升级转换在 optimization.disable-data-fixer 启用时不可用" +} comments { _v.comment = [ @@ -84,7 +88,15 @@ comments { "配置文件版本号,请勿编辑" ] locale.comment = "语言/国际化相关设置" - optimization.comment = "服务端优化相关设置" + optimization { + comment = "服务端优化相关设置" + disable-data-fixer.comment = [ + "关闭用于升级存档数据的 DataFixerUpper 系统" + "这将可能加快启动速度和地图加载速度,并减少 80-200mb 的内存占用" + "Arclight 及其开发者不对任何数据丢失或损害负责" + "请不要在生产环境中使用" + ] + } async-catcher.comment = [ "异步捕获相关设置" "Async Catcher 共有四种模式"