fix: 与reden断点不兼容的问题

This commit is contained in:
Disy authored and zly2006 committed 2024-07-11 12:14:02 +08:00
1 parent 01944bd5b4
commit ad9c61cd1a
22 files changed
+490 -57

No files matched your search

@@ -0,0 +1,15 @@
package com.github.zly2006.carpetslsaddition.mixin.block;
import com.google.common.cache.LoadingCache;
import net.minecraft.block.pattern.BlockPattern;
import net.minecraft.block.pattern.CachedBlockPosition;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(BlockPattern.class)
public interface BlockPatternTestTransformInvoker {
@Invoker("testTransform")
BlockPattern.Result invokeTestTransform(BlockPos frontTopLeft, Direction forwards, Direction up, LoadingCache<BlockPos, CachedBlockPosition> cache);
}
@@ -1,6 +1,6 @@
package com.github.zly2006.carpetslsaddition.mixin.block;
import com.github.zly2006.carpetslsaddition.PlayerAccess;
import com.github.zly2006.carpetslsaddition.util.access.PlayerAccess;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
@@ -0,0 +1,23 @@
package com.github.zly2006.carpetslsaddition.mixin.block;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.RedstoneWireBlock;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(value = RedstoneWireBlock.class, priority = 1)
public class MixinRedstoneWireBlock {
@Redirect(method = "getRenderConnectionType(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;Z)Lnet/minecraft/block/enums/WireConnection;", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;getBlock()Lnet/minecraft/block/Block;"))
public Block redirectConnectionBlockState(BlockState instance) {
if (SLSCarpetSettings.oldRedstoneConnectionLogic) {
return Blocks.AIR;
}
else {
return instance.getBlock();
}
}
}
@@ -1,9 +1,19 @@
package com.github.zly2006.carpetslsaddition.mixin.carpet;
import carpet.api.settings.CarpetRule;
import carpet.api.settings.SettingsManager;
import com.github.zly2006.carpetslsaddition.SettingsManagerAccessor;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.util.NeighborUpdaterChanger;
import com.github.zly2006.carpetslsaddition.util.access.SettingsManagerAccessor;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.server.world.ServerWorld;
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.callback.CallbackInfoReturnable;
@Mixin(value = SettingsManager.class, remap = false)
public abstract class MixinSettingsManager implements SettingsManagerAccessor {
@@ -13,4 +23,21 @@ public abstract class MixinSettingsManager implements SettingsManagerAccessor {
public void loadSettings() {
this.loadConfigurationFromConf();
}
@Inject(method = "setRule", at = @At(value = "INVOKE", target = "Lcarpet/utils/Messenger;m(Lnet/minecraft/server/command/ServerCommandSource;[Ljava/lang/Object;)V", shift = At.Shift.BEFORE))
private void injectSetRule(ServerCommandSource source, CarpetRule<?> rule, String newValue, CallbackInfoReturnable<Integer> cir) {
if ("maxUpdateQueueSize".equals(rule.name())) {
MinecraftServer server = ServerMain.server;
if (server != null)
{
server.execute(() -> {
for (ServerWorld world : server.getWorlds())
{
((NeighborUpdaterChanger)world).useRewriteChainNeighborUpdater(SLSCarpetSettings.maxUpdateQueueSize > -1);
}
});
}
}
}
}
@@ -0,0 +1,133 @@
package com.github.zly2006.carpetslsaddition.mixin.entity;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import com.github.zly2006.carpetslsaddition.mixin.block.BlockPatternTestTransformInvoker;
import com.google.common.cache.LoadingCache;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.block.entity.EndGatewayBlockEntity;
import net.minecraft.block.entity.EndPortalBlockEntity;
import net.minecraft.block.pattern.BlockPattern;
import net.minecraft.block.pattern.CachedBlockPosition;
import net.minecraft.entity.boss.dragon.EnderDragonFight;
import net.minecraft.entity.decoration.EndCrystalEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.Heightmap;
import net.minecraft.world.chunk.WorldChunk;
import net.minecraft.world.gen.feature.EndPortalFeature;
import net.minecraft.world.WorldView;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List;
@Mixin(EnderDragonFight.class)
public class MixinEnderDragonFight {
@Shadow
@Final
private ServerWorld world;
@Shadow
@Final
private BlockPattern endPortalPattern;
@Shadow
private BlockPos exitPortalLocation;
@Shadow
private boolean doLegacyCheck;
@Unique
private int defaultChunkX = -8;
@Unique
private int defaultChunkZ = -8;
@Unique
private int defaultOriginY = -1;
/**
* @author Disy920
* @reason Optimize the search process of the end portal
*/
@Overwrite
private @Nullable BlockPattern.Result findEndPortal() {
int i,j;
if(!SLSCarpetSettings.optimizedOnDragonRespawn) {
defaultChunkX = -8;
defaultChunkZ = -8;
}
for(i = defaultChunkX; i <= 8; ++i) {
for(j = defaultChunkZ; j <= 8; ++j) {
WorldChunk worldChunk = this.world.getChunk(i, j);
for(BlockEntity blockEntity : worldChunk.getBlockEntities().values()) {
if(SLSCarpetSettings.optimizedOnDragonRespawn && blockEntity instanceof EndGatewayBlockEntity) continue;
if (blockEntity instanceof EndPortalBlockEntity) {
BlockPattern.Result result = this.endPortalPattern.searchAround(this.world, blockEntity.getPos());
if (result != null) {
BlockPos blockPos = result.translate(3, 3, 3).getBlockPos();
if (this.exitPortalLocation == null) {
this.exitPortalLocation = blockPos;
}
defaultChunkX = i;
defaultChunkZ = j;
return result;
}
}
}
}
}
if(this.doLegacyCheck || this.exitPortalLocation == null){
if(SLSCarpetSettings.optimizedOnDragonRespawn && defaultOriginY != -1) {
i = defaultOriginY;
}
else {
i = this.world.getTopPosition(Heightmap.Type.MOTION_BLOCKING, EndPortalFeature.offsetOrigin(BlockPos.ORIGIN)).getY();
}
boolean notFirstSearch = false;
for(j = i; j >= 0; --j) {
BlockPattern.Result result2;
if(SLSCarpetSettings.optimizedOnDragonRespawn && notFirstSearch) {
result2 = partialSearchAround(this.endPortalPattern, this.world, new BlockPos(EndPortalFeature.offsetOrigin(BlockPos.ORIGIN).getX(), j, EndPortalFeature.offsetOrigin(BlockPos.ORIGIN).getZ()));
}
else{
result2 = this.endPortalPattern.searchAround(this.world, new BlockPos(EndPortalFeature.offsetOrigin(BlockPos.ORIGIN).getX(), j, EndPortalFeature.offsetOrigin(BlockPos.ORIGIN).getZ()));
}
if (result2 != null) {
if (this.exitPortalLocation == null) {
this.exitPortalLocation = result2.translate(3, 3, 3).getBlockPos();
}
defaultOriginY = j;
return result2;
}
notFirstSearch = true;
}
}
return null;
}
@Inject(method = "respawnDragon(Ljava/util/List;)V", at = @At("HEAD"))
private void resetCache(List<EndCrystalEntity> crystals, CallbackInfo ci) {
this.defaultChunkX = -8;
this.defaultChunkZ = -8;
this.defaultOriginY = -1;
}
@Unique
private BlockPattern.Result partialSearchAround(BlockPattern pattern, WorldView world, BlockPos pos) {
LoadingCache<BlockPos, CachedBlockPosition> loadingCache = BlockPattern.makeCache(world, false);
int i = Math.max(Math.max(pattern.getWidth(), pattern.getHeight()), pattern.getDepth());
for (BlockPos blockPos : BlockPos.iterate(pos, pos.add(i - 1, 0, i - 1))) {
for (Direction direction : Direction.values()) {
for (Direction direction2 : Direction.values()) {
BlockPattern.Result result;
if (direction2 == direction || direction2 == direction.getOpposite() || (result = ((BlockPatternTestTransformInvoker)pattern).invokeTestTransform(blockPos, direction, direction2, loadingCache)) == null) continue;
return result;
}
}
}
return null;
}
}
@@ -1,6 +1,6 @@
package com.github.zly2006.carpetslsaddition.mixin.entity;
import com.github.zly2006.carpetslsaddition.PlayerAccess;
import com.github.zly2006.carpetslsaddition.util.access.PlayerAccess;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.EquipmentSlot;
@@ -1,6 +1,6 @@
package com.github.zly2006.carpetslsaddition.mixin.item;
import com.github.zly2006.carpetslsaddition.PlayerAccess;
import com.github.zly2006.carpetslsaddition.util.access.PlayerAccess;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.entity.player.PlayerEntity;
@@ -0,0 +1,24 @@
package com.github.zly2006.carpetslsaddition.mixin.server;
import com.github.zly2006.carpetslsaddition.util.access.ServerAccess;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.server.dedicated.MinecraftDedicatedServer;
import net.minecraft.server.dedicated.ServerPropertiesLoader;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Environment(EnvType.SERVER)
@Mixin(MinecraftDedicatedServer.class)
public class MixinMinecraftDedicatedServer implements ServerAccess {
@Shadow
@Final
private ServerPropertiesLoader propertiesLoader;
@Override
public ServerPropertiesLoader getPropertiesLoader() {
return propertiesLoader;
}
}
@@ -1,46 +0,0 @@
package com.github.zly2006.carpetslsaddition.mixin.world;
import com.github.zly2006.carpetslsaddition.SLSCarpetSettings;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.block.ChainRestrictedNeighborUpdater;
import org.spongepowered.asm.mixin.Final;
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.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.util.ArrayDeque;
import java.util.List;
@Mixin(ChainRestrictedNeighborUpdater.class)
public class MixinChainRestrictedNeighborUpdater {
@Shadow
@Final
private ArrayDeque<?> queue;
@Shadow
@Final
private List<?> pending;
@Shadow
private int depth;
@Inject(method = "enqueue", at = @At(value = "INVOKE", target = "Ljava/util/ArrayDeque;push(Ljava/lang/Object;)V"), cancellable = true, locals = LocalCapture.CAPTURE_FAILSOFT)
public void injectEnqueue(BlockPos pos, ChainRestrictedNeighborUpdater.Entry entry, CallbackInfo ci, boolean bl) {
int maxSize = SLSCarpetSettings.maxUpdateQueueSize;
if (maxSize > 0) {
if (this.depth + 1 > maxSize) {
this.queue.clear();
this.pending.clear();
this.depth = 0;
bl = true;
Throwable e = new OutOfMemoryError("Create by Carpet-SLS-Addition: The update queue exceeded the maximum allowed allocation of heap space set by SLS Addition!");
e.printStackTrace();
ci.cancel();
}
}
}
}
@@ -0,0 +1,43 @@
package com.github.zly2006.carpetslsaddition.mixin.world;
import com.github.zly2006.carpetslsaddition.ServerMain;
import com.github.zly2006.carpetslsaddition.block.RewriteChainRestrictedNeighborUpdater;
import com.github.zly2006.carpetslsaddition.util.NeighborUpdaterChanger;
import com.github.zly2006.carpetslsaddition.util.access.ServerAccess;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.world.World;
import net.minecraft.world.block.NeighborUpdater;
import org.spongepowered.asm.mixin.*;
@Mixin(World.class)
public abstract class MixinWorld implements NeighborUpdaterChanger {
@Mutable
@Shadow
@Final
protected NeighborUpdater neighborUpdater;
@Unique
private NeighborUpdater previousUpdater = null;
@Override
public void useRewriteChainNeighborUpdater(boolean use) {
if (use) {
this.previousUpdater = this.neighborUpdater;
int maxDepth;
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.SERVER) {
maxDepth = ((ServerAccess) ServerMain.server).getPropertiesLoader().getPropertiesHandler().maxChainedNeighborUpdates;
}
else {
maxDepth = 1000000;
}
this.neighborUpdater = new RewriteChainRestrictedNeighborUpdater((World)(Object)this, maxDepth);
}
else {
this.neighborUpdater = previousUpdater;
}
}
}