Merge pull request #34 from gnembon/portals
portal caching, ignored item not creating portals issue on purpose
This commit is contained in:
5 files changed
+149
-26
No files matched your search
@@ -1,41 +1,32 @@
|
||||
package carpet;
|
||||
|
||||
import carpet.fakes.MinecraftServer_motdInterface;
|
||||
import carpet.fakes.PortalForcerInterface;
|
||||
import carpet.utils.Messenger;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.FileReader;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
//import carpet.helpers.SpawnChunks;
|
||||
import carpet.fakes.MinecraftServer_motdInterface;
|
||||
import carpet.utils.Messenger;
|
||||
import net.minecraft.server.command.CommandSource;
|
||||
import net.minecraft.server.command.ServerCommandSource;
|
||||
import net.minecraft.server.network.ServerPlayerEntity;
|
||||
import net.minecraft.server.dedicated.DedicatedServer;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.world.dimension.DimensionType;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
|
||||
public class CarpetSettings
|
||||
{
|
||||
@@ -136,7 +127,9 @@ public class CarpetSettings
|
||||
rule("commandPlayer", "commands", "Enables /player command to control/spawn players").isACommand().wip(),
|
||||
rule("carpets", "survival", "Placing carpets may issue carpet commands for non-op players"),
|
||||
rule("missingTools", "survival", "Pistons, Glass and Sponge can be broken faster with their appropriate tools").wip(),
|
||||
rule("portalCaching", "survival experimental", "Alternative, persistent caching strategy for nether portals").wip(),
|
||||
rule("portalCaching", "survival experimental", "Alternative, persistent caching strategy for nether portals").validate(
|
||||
(s, n) -> s.getMinecraftServer().getWorlds().forEach(w -> ((PortalForcerInterface)w.getPortalForcer()).invalidateCache())
|
||||
),
|
||||
rule("calmNetherFires", "experimental", "Permanent fires don't schedule random updates").wip(),
|
||||
rule("fillUpdates", "creative", "fill/clone/setblock and structure blocks cause block updates").defaultTrue().boolAccelerate(),
|
||||
rule("pushLimit", "creative","Customizable piston push limit")
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package carpet.fakes;
|
||||
|
||||
public interface PortalForcerInterface
|
||||
{
|
||||
void invalidateCache();
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.fakes.PortalForcerInterface;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.PortalBlock;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.IWorld;
|
||||
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(PortalBlock.class)
|
||||
public class PortalBlock_portalCachingMixin
|
||||
{
|
||||
@Inject(method = "createPortalAt", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/block/PortalBlock$AreaHelper;createPortal()V"
|
||||
))
|
||||
private void onCreatePortal(IWorld iWorld_1, BlockPos blockPos_1, CallbackInfoReturnable<Boolean> cir)
|
||||
{
|
||||
if (!iWorld_1.isClient() && CarpetSettings.getBool("portalCaching"))
|
||||
{
|
||||
((PortalForcerInterface)((ServerWorld)iWorld_1).getPortalForcer()).invalidateCache();
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "getStateForNeighborUpdate", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/block/Block;getDefaultState()Lnet/minecraft/block/BlockState;"
|
||||
))
|
||||
private void getAirBlockState(BlockState blockState_1, Direction direction_1, BlockState blockState_2, IWorld iWorld_1, BlockPos blockPos_1, BlockPos blockPos_2, CallbackInfoReturnable<BlockState> cir)
|
||||
{
|
||||
if (!iWorld_1.isClient() && CarpetSettings.getBool("portalCaching"))
|
||||
{
|
||||
((PortalForcerInterface)((ServerWorld)iWorld_1).getPortalForcer()).invalidateCache();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package carpet.mixins;
|
||||
|
||||
import carpet.CarpetSettings;
|
||||
import carpet.fakes.PortalForcerInterface;
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.server.world.ChunkTicketType;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.ChunkPos;
|
||||
import net.minecraft.util.math.ColumnPos;
|
||||
import net.minecraft.world.PortalForcer;
|
||||
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.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Mixin(PortalForcer.class)
|
||||
public class PortalForcer_portalCachingMixin implements PortalForcerInterface
|
||||
{
|
||||
@Shadow @Final private ServerWorld world;
|
||||
private Map<ColumnPos, Object> storedTicketInfos = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void invalidateCache()
|
||||
{
|
||||
storedTicketInfos.clear();
|
||||
}
|
||||
|
||||
@Inject(method = "createPortal", at = @At("HEAD"))
|
||||
private void portalSpawnedByTheGame(Entity entity_1, CallbackInfoReturnable<Boolean> cir)
|
||||
{
|
||||
invalidateCache();
|
||||
}
|
||||
|
||||
@Redirect(method = "getPortal", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Ljava/util/Map;get(Ljava/lang/Object;)Ljava/lang/Object;"
|
||||
))
|
||||
private Object /* private TicketInfo */ getTicketInfo(Map map, Object /* ColumnPos */ key)
|
||||
{
|
||||
//Do the dance with ticketinfos. If vanilla has one, we gonna borrow, if vanilla is missing, we supply
|
||||
if (!CarpetSettings.getBool("portalCaching"))
|
||||
return map.get(key);
|
||||
Object ticketInfo = map.get(key);
|
||||
if (ticketInfo != null)
|
||||
{
|
||||
storedTicketInfos.put((ColumnPos) key, ticketInfo);
|
||||
return ticketInfo;
|
||||
}
|
||||
ticketInfo = storedTicketInfos.get(key);
|
||||
if (ticketInfo != null)
|
||||
{
|
||||
// vanilla got removed, but we stored it meaning we not only need to add it but also let it chunkload
|
||||
map.put(key, ticketInfo);
|
||||
ColumnPos cpos = (ColumnPos)key;
|
||||
BlockPos fakePos = new BlockPos(((ColumnPos) key).x, 0, ((ColumnPos) key).z);
|
||||
world.method_14178().addTicket(ChunkTicketType.PORTAL, new ChunkPos(fakePos), 3, (ColumnPos) key);
|
||||
}
|
||||
return ticketInfo;
|
||||
}
|
||||
|
||||
@Redirect(method = "getPortal", at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"
|
||||
))
|
||||
private Object /* TicketInfo */ putNewTicket(Map map, Object /*ColumnPos */ key, Object /*TicketInfo */ value)
|
||||
{
|
||||
if (CarpetSettings.getBool("portalCaching"))
|
||||
storedTicketInfos.put((ColumnPos) key, value);
|
||||
return map.put(key, value);
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,9 @@
|
||||
"ItemUsageContext_cactusMixin",
|
||||
"DispenserBehaviour_cactusMixin",
|
||||
|
||||
"PortalForcer_portalCachingMixin",
|
||||
"PortalBlock_portalCachingMixin",
|
||||
|
||||
"HopperBlockEntityMixin",
|
||||
"ContainerMixin",
|
||||
"ClientConnectionMixin",
|
||||
|
||||
Reference in new issue
Block a user