diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a6aa170..da2d5e1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2101.1.4] + +### Added +* Added protection for pistons moving blocks, including large block structure (e.g. vanilla-style flying machines) + * Enabled by default; can be disabled via 'piston_protection' server setting + * When enabled, pistons cannot push blocks from the chunk the piston is in to another chunk if the new chunk is owned by a different team, and that team does not have public block-edit permissions + * Similar restrictions apply to blocks which would be destroyed by piston moving +* Add client config setting "Pointer Icon Mode" to control the appearance of the player pointer icon on maps + * Can display the player face, a heading arrow, or both +* Displayed component values for the minimap can now be configured via the client config screen + +### Fixed +* Possibly fixed an issue leading to hangs on server shutdown (hard to know for certain; the issue is difficult to reproduce) +* Fixed output of `/ftbchunks admin unload_everything` being misleading + * The command ran correctly, un-forceloading all forceloaded chunks, but reported the number of _all_ claimed chunks, not just the forceloaded ones +* Fixed colouring for some blocks (primarily redstone-related) on the map/minimap leading to an ugly-looking artifacts on the map +* Integrated Dynamics Menril Leaves now show up as light blue on the map instead of the default green + ## [2101.1.3] ### Changed diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java index 91418d4b..336910d0 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunks.java @@ -12,10 +12,7 @@ import dev.architectury.utils.Env; import dev.architectury.utils.EnvExecutor; import dev.architectury.utils.value.IntValue; -import dev.ftb.mods.ftbchunks.api.ClaimedChunk; -import dev.ftb.mods.ftbchunks.api.FTBChunksAPI; -import dev.ftb.mods.ftbchunks.api.FTBChunksProperties; -import dev.ftb.mods.ftbchunks.api.Protection; +import dev.ftb.mods.ftbchunks.api.*; import dev.ftb.mods.ftbchunks.client.FTBChunksClient; import dev.ftb.mods.ftbchunks.data.*; import dev.ftb.mods.ftbchunks.net.*; @@ -62,14 +59,11 @@ import org.jetbrains.annotations.Nullable; import java.util.*; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; public class FTBChunks { public static final String MOD_ID = "ftbchunks"; public static final Logger LOGGER = LogManager.getLogger("FTB Chunks"); public static final Gson GSON = new GsonBuilder().disableHtmlEscaping().setLenient().create(); - public static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor(); public static FTBChunks instance; @@ -600,4 +594,5 @@ private void serverTickPost(MinecraftServer minecraftServer) { ClaimExpirationManager.INSTANCE.tick(minecraftServer); LongRangePlayerTracker.INSTANCE.tick(minecraftServer); } + } diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java index 3e6e0023..d2bcbd73 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksCommands.java @@ -504,9 +504,8 @@ private static int setExtraForceLoadChunks(CommandSourceStack source, ServerPlay private static int unclaimEverything(CommandSourceStack source) { int claimedChunks = 0; - for (ClaimedChunkImpl c : new ArrayList<>(claimManager().getAllClaimedChunks())) { + for (ClaimedChunk c : new ArrayList<>(claimManager().getAllClaimedChunks())) { c.getTeamData().unclaim(source, c.getPos(), false); - c.getTeamData().markDirty(); claimedChunks++; } int finalClaimedChunks = claimedChunks; @@ -516,10 +515,9 @@ private static int unclaimEverything(CommandSourceStack source) { private static int unclaimDimension(CommandSourceStack source, ResourceKey dim) { int claimedChunks = 0; - for (ClaimedChunkImpl c : new ArrayList<>(claimManager().getAllClaimedChunks())) { + for (ClaimedChunk c : new ArrayList<>(claimManager().getAllClaimedChunks())) { if (source.getLevel().dimension().equals(dim)) { c.getTeamData().unclaim(source, c.getPos(), false); - c.getTeamData().markDirty(); claimedChunks++; } } @@ -534,13 +532,17 @@ private static int unclaimDimension(CommandSourceStack source) { private static int unloadEverything(CommandSourceStack source) { int unloadedChunks = 0; - for (ClaimedChunkImpl c : new ArrayList<>(claimManager().getAllClaimedChunks())) { - c.getTeamData().unForceLoad(source, c.getPos(), false); - c.getTeamData().markDirty(); - unloadedChunks++; + int totalChunks = 0; + for (ClaimedChunk c : claimManager().getAllClaimedChunks()) { + if (c.isForceLoaded()) { + c.getTeamData().unForceLoad(source, c.getPos(), false); + unloadedChunks++; + } + totalChunks++; } - int finalUnloadedChunks = unloadedChunks; - source.sendSuccess(() -> Component.translatable("ftbchunks.command.unloaded", finalUnloadedChunks), true); + final int finalUnloadedChunks = unloadedChunks; + final int finalTotalChunks = totalChunks; + source.sendSuccess(() -> Component.translatable("ftbchunks.commands.unloaded", finalUnloadedChunks, finalTotalChunks), true); return Command.SINGLE_SUCCESS; } diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java index 443c92e2..12c8179d 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/FTBChunksWorldConfig.java @@ -41,6 +41,8 @@ public interface FTBChunksWorldConfig { .comment("If true, the player must have the 'ftbchunks_mapping' Game stage to be able to use the map and minimap.\nRequires KubeJS and/or Gamestages to be installed."); BooleanValue LOCATION_MODE_OVERRIDE = CONFIG.addBoolean("location_mode_override", false) .comment("If true, \"Location Visibility\" team settings are ignored, and all players can see each other anywhere on the map."); + BooleanValue PISTON_PROTECTION = CONFIG.addBoolean("piston_protection", true) + .comment("If true, pistons are prevented from pushing/pulling blocks across claims owned by different teams (unless the target claim has public 'edit block' permissions defined). If 'disable_protection' is set to true, this setting is ignored."); SNBTConfig FAKE_PLAYERS = CONFIG.addGroup("fake_players"); EnumValue ALLOW_FAKE_PLAYERS = FAKE_PLAYERS.addEnum("fake_players", NameMap.of(ProtectionPolicy.CHECK, ProtectionPolicy.values()).create()) diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/client/FTBChunksClient.java b/common/src/main/java/dev/ftb/mods/ftbchunks/client/FTBChunksClient.java index cb1eb4b7..4f85fda0 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/client/FTBChunksClient.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/client/FTBChunksClient.java @@ -144,12 +144,16 @@ import java.util.Optional; import java.util.Set; import java.util.UUID; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.function.Function; import java.util.stream.Collectors; public enum FTBChunksClient { INSTANCE; + public static final ExecutorService MAP_EXECUTOR = Executors.newSingleThreadExecutor(); + public static final ResourceLocation WAYPOINT_BEAM = FTBChunksAPI.rl("textures/waypoint_beam.png"); private static final ResourceLocation BUTTON_ID_MAP = FTBChunksAPI.rl("open_gui"); private static final ResourceLocation BUTTON_ID_CLAIM = FTBChunksAPI.rl("open_claim_gui"); @@ -1106,8 +1110,15 @@ private void mapIcons(MapIconEvent event) { } if (!event.getMapType().isMinimap()) { - event.add(new EntityMapIcon(mc.player, FaceIcon.getFace(mc.player.getGameProfile()))); - event.add(new PointerIcon()); + PointerIconMode pointerIconMode = FTBChunksClientConfig.POINTER_ICON_MODE.get(); + + if (pointerIconMode.showFace()) { + event.add(new EntityMapIcon(mc.player, FaceIcon.getFace(mc.player.getGameProfile()))); + } + + if (pointerIconMode.showPointer()) { + event.add(new PointerIcon()); + } } } @@ -1158,7 +1169,7 @@ public void handlePacket(ClientboundLevelChunkWithLightPacket p) { public void queueOrExecute(MapTask task) { // Implement this config later - FTBChunks.EXECUTOR.execute(task); + MAP_EXECUTOR.execute(task); } public void handlePacket(ClientboundBlockUpdatePacket p) { diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/client/FTBChunksClientConfig.java b/common/src/main/java/dev/ftb/mods/ftbchunks/client/FTBChunksClientConfig.java index 0fc45261..f3bf098e 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/client/FTBChunksClientConfig.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/client/FTBChunksClientConfig.java @@ -2,12 +2,13 @@ import dev.architectury.networking.NetworkManager; import dev.architectury.platform.Platform; +import dev.ftb.mods.ftbchunks.EntityTypeBoolMapValue; import dev.ftb.mods.ftbchunks.FTBChunks; import dev.ftb.mods.ftbchunks.FTBChunksWorldConfig; -import dev.ftb.mods.ftbchunks.EntityTypeBoolMapValue; import dev.ftb.mods.ftbchunks.client.map.BiomeBlendMode; import dev.ftb.mods.ftbchunks.client.map.MapManager; import dev.ftb.mods.ftbchunks.client.map.MapMode; +import dev.ftb.mods.ftbchunks.client.minimap.MinimapComponentConfig; import dev.ftb.mods.ftbchunks.client.minimap.components.BiomeComponent; import dev.ftb.mods.ftbchunks.client.minimap.components.DebugComponent; import dev.ftb.mods.ftbchunks.client.minimap.components.FPSComponent; @@ -19,7 +20,13 @@ import dev.ftb.mods.ftblibrary.config.ConfigGroup; import dev.ftb.mods.ftblibrary.config.ui.EditConfigScreen; import dev.ftb.mods.ftblibrary.snbt.SNBTCompoundTag; -import dev.ftb.mods.ftblibrary.snbt.config.*; +import dev.ftb.mods.ftblibrary.snbt.config.BooleanValue; +import dev.ftb.mods.ftblibrary.snbt.config.DoubleValue; +import dev.ftb.mods.ftblibrary.snbt.config.EnumValue; +import dev.ftb.mods.ftblibrary.snbt.config.IntValue; +import dev.ftb.mods.ftblibrary.snbt.config.SNBTConfig; +import dev.ftb.mods.ftblibrary.snbt.config.StringListValue; +import dev.ftb.mods.ftblibrary.snbt.config.StringMapValue; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.screens.Screen; import net.minecraft.resources.ResourceLocation; @@ -82,8 +89,9 @@ public interface FTBChunksClientConfig { BooleanValue MINIMAP_PROPORTIONAL = MINIMAP.addBoolean("proportional", true).comment("Size minimap proportional to screen width (and scale)"); StringListValue MINIMAP_INFO_ORDER = MINIMAP.addStringList("info_order", Stream.of(PlayerPosInfoComponent.ID, BiomeComponent.ID, ZoneInfoComponent.ID, FPSComponent.ID, GameTimeComponent.ID, RealTimeComponent.ID, DebugComponent.ID).map(ResourceLocation::toString).toList()).excluded().comment("Info displayed under minimap"); StringListValue MINIMAP_INFO_HIDDEN = MINIMAP.addStringList("info_hidden", Stream.of(FPSComponent.ID, GameTimeComponent.ID, RealTimeComponent.ID, DebugComponent.ID).map(ResourceLocation::toString).toList()).excluded().comment("Info hidden under minimap"); - StringMapValue MINIMAP_SETTINGS = MINIMAP.add(new StringMapValue(MINIMAP, "info_settings", Collections.emptyMap())).comment("Settings for minimap info components"); + StringMapValue MINIMAP_SETTINGS = MINIMAP.add(new MinimapComponentConfig(MINIMAP, "info_settings", Collections.emptyMap())).comment("Settings for minimap info components"); EntityTypeBoolMapValue ENTITY_ICON = MINIMAP.add(new EntityTypeBoolMapValue(MINIMAP, "entity_icon", Collections.emptyMap())).comment("Entity icons on minimap"); + EnumValue POINTER_ICON_MODE = MINIMAP.addEnum("pointer_icon_mode", PointerIconMode.NAME_MAP).comment("Mode for the pointer icon to render on full screen minimap"); SNBTConfig ADVANCED = CONFIG.addGroup("advanced", 3); BooleanValue DEBUG_INFO = ADVANCED.addBoolean("debug_info", false).comment("Enables debug info"); diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/client/PointerIconMode.java b/common/src/main/java/dev/ftb/mods/ftbchunks/client/PointerIconMode.java new file mode 100644 index 00000000..1270cb77 --- /dev/null +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/client/PointerIconMode.java @@ -0,0 +1,28 @@ +package dev.ftb.mods.ftbchunks.client; + +import dev.ftb.mods.ftblibrary.config.NameMap; + +public enum PointerIconMode { + FACE(true, false), + POINTER(false, true), + BOTH(true, true), + ; + + public static final NameMap NAME_MAP = NameMap.of(BOTH, values()).baseNameKey("ftbchunks.minimap.pointer_icon_mode").create(); + + private final boolean face; + private final boolean pointer; + + PointerIconMode(boolean face, boolean pointer) { + this.face = face; + this.pointer = pointer; + } + + public boolean showFace() { + return face; + } + + public boolean showPointer() { + return pointer; + } +} \ No newline at end of file diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/client/gui/ChunkScreen.java b/common/src/main/java/dev/ftb/mods/ftbchunks/client/gui/ChunkScreen.java index d5222957..c3309a07 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/client/gui/ChunkScreen.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/client/gui/ChunkScreen.java @@ -137,7 +137,7 @@ protected class CustomTopPanel extends Panel { public CustomTopPanel() { super(ChunkScreen.this); - closeButton = new SimpleButton(this, Component.translatable("gui.close"), Icons.CLOSE, + closeButton = new SimpleButton(this, Component.translatable("gui.close"), Icons.CANCEL, (btn, mb) -> doCancel()) .setForceButtonSize(false); diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/client/gui/LargeMapScreen.java b/common/src/main/java/dev/ftb/mods/ftbchunks/client/gui/LargeMapScreen.java index dc894e73..82ea400c 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/client/gui/LargeMapScreen.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/client/gui/LargeMapScreen.java @@ -507,7 +507,7 @@ public Component getTitle() { private class ClearDeathPointButton extends SimpleButton { public ClearDeathPointButton(Panel panel) { - super(panel, Component.translatable("ftbchunks.gui.clear_deathpoints"), Icons.CLOSE, (b, m) -> { + super(panel, Component.translatable("ftbchunks.gui.clear_deathpoints"), Icons.CANCEL, (b, m) -> { if (getWaypointManager().removeIf(wp -> wp.getType() == WaypointType.DEATH)) { refreshWidgets(); } diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/client/gui/WaypointShareMenu.java b/common/src/main/java/dev/ftb/mods/ftbchunks/client/gui/WaypointShareMenu.java index 86a3bbb2..6c8856b5 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/client/gui/WaypointShareMenu.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/client/gui/WaypointShareMenu.java @@ -31,7 +31,7 @@ public static Optional makeShareMenu(Player sharingPlayer, Wayp b -> shareWaypoint(waypoint, ShareWaypointPacket.ShareType.SERVER, List.of()))); } if (FTBChunksWorldConfig.WAYPOINT_SHARING_PARTY.get()) { - items.add(new ContextMenuItem(Component.translatable("ftbchunks.waypoint.share.party"), Icons.BELL, + items.add(new ContextMenuItem(Component.translatable("ftbchunks.waypoint.share.party"), Icons.FRIENDS_GROUP, b -> shareWaypoint(waypoint, ShareWaypointPacket.ShareType.PARTY, List.of()))); } if (FTBChunksWorldConfig.WAYPOINT_SHARING_PLAYERS.get()) { diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/client/map/MapDimension.java b/common/src/main/java/dev/ftb/mods/ftbchunks/client/map/MapDimension.java index 10a797a7..ac007131 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/client/map/MapDimension.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/client/map/MapDimension.java @@ -4,6 +4,7 @@ import dev.ftb.mods.ftbchunks.FTBChunks; import dev.ftb.mods.ftbchunks.api.FTBChunksAPI; import dev.ftb.mods.ftbchunks.client.ClientTaskQueue; +import dev.ftb.mods.ftbchunks.client.FTBChunksClient; import dev.ftb.mods.ftblibrary.math.XZ; import it.unimi.dsi.fastutil.longs.Long2IntMap; import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap; @@ -169,7 +170,7 @@ public void runMapTask() throws Exception { List regionList = ImmutableList.copyOf(getRegions().values()); if (!waypoints.isEmpty() || !regionList.isEmpty()) { - FTBChunks.EXECUTOR.execute(() -> { + FTBChunksClient.MAP_EXECUTOR.execute(() -> { try { writeData(waypoints, regionList); } catch (Exception ex) { diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/client/map/MapManager.java b/common/src/main/java/dev/ftb/mods/ftbchunks/client/map/MapManager.java index 89a32ee5..58376409 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/client/map/MapManager.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/client/map/MapManager.java @@ -240,7 +240,7 @@ public void runMapTask() throws Exception { .map(key -> String.format("#%03X %s", key.getIntKey(), key.getValue().location())) .collect(Collectors.toList()); - FTBChunks.EXECUTOR.execute(() -> { + FTBChunksClient.MAP_EXECUTOR.execute(() -> { try { Files.write(directory.resolve("dimensions.txt"), dimensionsList); Files.write(directory.resolve("block_map.txt"), blockColorIndexMapList); diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/client/map/MapRegion.java b/common/src/main/java/dev/ftb/mods/ftbchunks/client/map/MapRegion.java index 44eb6a9b..e3417615 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/client/map/MapRegion.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/client/map/MapRegion.java @@ -92,7 +92,7 @@ public MapRegionData getDataBlockingNoSync() { public MapRegionData getData() { if (data == null && !isLoadingData) { isLoadingData = true; - FTBChunks.EXECUTOR.execute(this::getDataBlocking); + FTBChunksClient.MAP_EXECUTOR.execute(this::getDataBlocking); } if (data != null) { @@ -115,7 +115,7 @@ public NativeImage getRenderedMapImage() { updateRenderedMapImage = false; mapImageLoaded = false; renderingMapImage = true; - FTBChunks.EXECUTOR.execute(new RenderMapImageTask(this)); + FTBChunksClient.MAP_EXECUTOR.execute(new RenderMapImageTask(this)); } return renderedMapImage; diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/client/map/MapRegionData.java b/common/src/main/java/dev/ftb/mods/ftbchunks/client/map/MapRegionData.java index d2d4db72..26f1ee9e 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/client/map/MapRegionData.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/client/map/MapRegionData.java @@ -1,6 +1,7 @@ package dev.ftb.mods.ftbchunks.client.map; import dev.ftb.mods.ftbchunks.FTBChunks; +import dev.ftb.mods.ftbchunks.client.FTBChunksClient; import dev.ftb.mods.ftbchunks.util.HeightUtils; import dev.ftb.mods.ftblibrary.math.XZ; @@ -160,7 +161,7 @@ public void write() throws IOException { } } - FTBChunks.EXECUTOR.execute(() -> { + FTBChunksClient.MAP_EXECUTOR.execute(() -> { try { writeData(chunkList, dataImage, foliageImage, grassImage, waterImage, blocksImage); } catch (Exception ex) { diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/client/minimap/MinimapComponentConfig.java b/common/src/main/java/dev/ftb/mods/ftbchunks/client/minimap/MinimapComponentConfig.java new file mode 100644 index 00000000..7fac0ed1 --- /dev/null +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/client/minimap/MinimapComponentConfig.java @@ -0,0 +1,44 @@ +package dev.ftb.mods.ftbchunks.client.minimap; + +import dev.ftb.mods.ftbchunks.client.gui.MinimapInfoSortScreen; +import dev.ftb.mods.ftblibrary.config.ConfigCallback; +import dev.ftb.mods.ftblibrary.config.ConfigGroup; +import dev.ftb.mods.ftblibrary.config.ConfigValue; +import dev.ftb.mods.ftblibrary.snbt.config.SNBTConfig; +import dev.ftb.mods.ftblibrary.snbt.config.StringMapValue; +import dev.ftb.mods.ftblibrary.ui.Widget; +import dev.ftb.mods.ftblibrary.ui.input.MouseButton; +import net.minecraft.network.chat.Component; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; + +public class MinimapComponentConfig extends StringMapValue { + + public MinimapComponentConfig(@Nullable SNBTConfig c, String n, Map def) { + super(c, n, def); + } + + + @Override + public void createClientConfig(ConfigGroup group) { + group.add(key, new MinimapComponentConfigValue(), get(), stringBooleanMap -> { + }, defaultValue); + } + + public static class MinimapComponentConfigValue extends ConfigValue> { + + @Override + public void onClicked(Widget clickedWidget, MouseButton button, ConfigCallback callback) { + new MinimapInfoSortScreen().openGui(); + } + + @Override + public Component getStringForGUI(@Nullable Map v) { + if (v == null) { + return super.getStringForGUI(null); + } + return Component.translatable("ftbchunks.gui.sort_minimap_info"); + } + } +} diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/core/mixin/PistonBaseBlockMixin.java b/common/src/main/java/dev/ftb/mods/ftbchunks/core/mixin/PistonBaseBlockMixin.java new file mode 100644 index 00000000..956dc543 --- /dev/null +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/core/mixin/PistonBaseBlockMixin.java @@ -0,0 +1,26 @@ +package dev.ftb.mods.ftbchunks.core.mixin; + +import com.llamalad7.mixinextras.sugar.Local; +import dev.architectury.platform.Platform; +import dev.ftb.mods.ftbchunks.api.FTBChunksProperties; +import dev.ftb.mods.ftbchunks.util.PistonHelper; +import dev.ftb.mods.ftbteams.api.property.PrivacyProperty; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.piston.PistonBaseBlock; +import net.minecraft.world.level.block.piston.PistonStructureResolver; +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(PistonBaseBlock.class) +public class PistonBaseBlockMixin { + @Inject(method = "moveBlocks", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/piston/PistonStructureResolver;getToPush()Ljava/util/List;"), cancellable = true) + public void onMoveBlocks(Level level, BlockPos blockPos, Direction direction, boolean extending, CallbackInfoReturnable cir, @Local PistonStructureResolver pistonStructureResolver) { + if (PistonHelper.shouldPreventPistonMovement(level, blockPos, pistonStructureResolver)) { + cir.setReturnValue(false); + } + } +} diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/core/mixin/UtilMixin.java b/common/src/main/java/dev/ftb/mods/ftbchunks/core/mixin/UtilMixin.java index 02f48a54..fd20afca 100644 --- a/common/src/main/java/dev/ftb/mods/ftbchunks/core/mixin/UtilMixin.java +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/core/mixin/UtilMixin.java @@ -1,6 +1,7 @@ package dev.ftb.mods.ftbchunks.core.mixin; import dev.ftb.mods.ftbchunks.FTBChunks; +import dev.ftb.mods.ftbchunks.client.FTBChunksClient; import net.minecraft.Util; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -14,17 +15,17 @@ public abstract class UtilMixin { @Inject(method = "shutdownExecutors", at = @At("RETURN")) private static void shutdownExecutorsFTBC(CallbackInfo ci) { FTBChunks.LOGGER.info("Shutting down map thread"); - FTBChunks.EXECUTOR.shutdown(); + FTBChunksClient.MAP_EXECUTOR.shutdown(); boolean b; try { - b = FTBChunks.EXECUTOR.awaitTermination(3L, TimeUnit.SECONDS); + b = FTBChunksClient.MAP_EXECUTOR.awaitTermination(3L, TimeUnit.SECONDS); } catch (InterruptedException var3) { b = false; } if (!b) { - FTBChunks.EXECUTOR.shutdownNow(); + FTBChunksClient.MAP_EXECUTOR.shutdownNow(); } } } diff --git a/common/src/main/java/dev/ftb/mods/ftbchunks/util/PistonHelper.java b/common/src/main/java/dev/ftb/mods/ftbchunks/util/PistonHelper.java new file mode 100644 index 00000000..2a17dc14 --- /dev/null +++ b/common/src/main/java/dev/ftb/mods/ftbchunks/util/PistonHelper.java @@ -0,0 +1,63 @@ +package dev.ftb.mods.ftbchunks.util; + +import dev.architectury.platform.Platform; +import dev.ftb.mods.ftbchunks.FTBChunksWorldConfig; +import dev.ftb.mods.ftbchunks.api.ClaimedChunk; +import dev.ftb.mods.ftbchunks.api.ClaimedChunkManager; +import dev.ftb.mods.ftbchunks.api.FTBChunksAPI; +import dev.ftb.mods.ftbchunks.api.FTBChunksProperties; +import dev.ftb.mods.ftblibrary.math.ChunkDimPos; +import dev.ftb.mods.ftbteams.api.property.PrivacyMode; +import dev.ftb.mods.ftbteams.api.property.PrivacyProperty; +import net.minecraft.Util; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.piston.PistonStructureResolver; + +import java.util.UUID; + +public class PistonHelper { + /** + * Check if a vanilla piston (or sticky piston) can work across claims. At least one of the following + * requirements must be met: + *
    + *
  • Piston protection is disabled in server config
  • + *
  • The moved blocks will all end up in a chunk owned by the same team as the piston base's chunk
  • + *
  • The moved blocks will all end up in an unclaimed chunk, or in a chunk that allows public "edit block" access
  • + *
+ * The same restrictions apply to any blocks that would be destroyed by the piston. + * @param level the level + * @param pistonPos position of the piston itself + * @param resolver the piston's structure resolver (with {@code resolve()} already called successfully), which can be used to determine the affected block positions + * @return true if the piston should be prevented from moving, false to let it move + */ + public static boolean shouldPreventPistonMovement(Level level, BlockPos pistonPos, PistonStructureResolver resolver) { + if (FTBChunksWorldConfig.PISTON_PROTECTION.get() && !FTBChunksWorldConfig.DISABLE_PROTECTION.get()) { + PrivacyProperty editProp = Platform.isFabric() ? + FTBChunksProperties.BLOCK_EDIT_AND_INTERACT_MODE : + FTBChunksProperties.BLOCK_EDIT_MODE; + ClaimedChunkManager mgr = FTBChunksAPI.api().getManager(); + ClaimedChunk srcClaim = mgr.getChunk(new ChunkDimPos(level, pistonPos)); + for (BlockPos pos : resolver.getToPush()) { + // check ownership of positions the blocks would be moving to + ClaimedChunk dstClaim = mgr.getChunk(new ChunkDimPos(level, pos.relative(resolver.getPushDirection()))); + if (prevent(editProp, srcClaim, dstClaim)) return true; + } + for (BlockPos pos : resolver.getToDestroy()) { + // check ownership of positions the blocks are in now + ClaimedChunk dstClaim = mgr.getChunk(new ChunkDimPos(level, pos)); + if (prevent(editProp, srcClaim, dstClaim)) return true; + } + } + return false; + } + + private static boolean prevent(PrivacyProperty editProp, ClaimedChunk srcClaim, ClaimedChunk dstClaim) { + if (srcClaim != dstClaim && dstClaim != null) { + UUID srcId = srcClaim == null ? Util.NIL_UUID : srcClaim.getTeamData().getTeam().getTeamId(); + UUID dstId = dstClaim.getTeamData().getTeam().getTeamId(); + return !srcId.equals(dstId) && dstClaim.getTeamData().getTeam().getProperty(editProp) != PrivacyMode.PUBLIC; + } + return false; + } +} diff --git a/common/src/main/resources/assets/ftbchunks/lang/en_us.json b/common/src/main/resources/assets/ftbchunks/lang/en_us.json index 05bb24cc..9a85a0d0 100644 --- a/common/src/main/resources/assets/ftbchunks/lang/en_us.json +++ b/common/src/main/resources/assets/ftbchunks/lang/en_us.json @@ -78,6 +78,10 @@ "ftbchunks.minimap.font_scale.tooltip": "Recommended to keep this to a multiple of 0.5", "ftbchunks.minimap.proportional": "Proportional sizing", "ftbchunks.minimap.proportional.tooltip": "When true, minimap size is proportional to 10%% of the screen width (modifiable by the Scale setting)\nWhen false, it is a fixed size regardless of screen resolution", + "ftbchunks.minimap.pointer_icon_mode": "Pointer Icon Mode", + "ftbchunks.minimap.pointer_icon_mode.both": "Both", + "ftbchunks.minimap.pointer_icon_mode.pointer": "Pointer", + "ftbchunks.minimap.pointer_icon_mode.face": "Face Icon", "sidebar_button.ftbchunks.chunks": "FTB Chunks: Map", "sidebar_button.ftbchunks.claim_chunks": "FTB Chunks: Claim Manager", "key.categories.ftbchunks": "FTB Chunks", @@ -202,6 +206,8 @@ "ftbchunks.require_game_stage.tooltip": "If true, players must have the 'ftbchunks_mapping' game stage (KubeJS and/or Gamestages required) to be able to open the map or see the minimap", "ftbchunks.location_mode_override": "Override Team \"Location Visibility\"", "ftbchunks.location_mode_override.tooltip": "If true, team \"Location Visibility\" settings are ignored, and all players can see each other anywhere on the map", + "ftbchunks.piston_protection": "Piston Protection", + "ftbchunks.piston_protection.tooltip": "If true, pistons may not push/pull blocks across claims owned by different teams (unless the block is entering/leaving a claim with block edit mode set to Public)\nIf 'disable_protection' is set to true, this setting is ignored.", "ftbchunks.fake_players.max_prevented_log_age": "Fake Player Prevented Access Log Age", "ftbchunks.fake_players.max_prevented_log_age.tooltip": "Age in days to keep logs of prevented fake player access\nNote: not fully implemented feature; will be used in future to display & control access by fake players to your claims", "ftbchunks.claim_result": "Chunks modified: %d / %d", @@ -290,6 +296,7 @@ "ftbchunks.gui.sort_minimap_info": "Minimap Info Settings", "ftbchunks.minimap.info_hidden": "Hidden Minimap Info", "ftbchunks.minimap.info_order": "Minimap info order", + "ftbchunks.minimap.info_settings": "Info Settings", "ftbchunks.show_wilderness.show_wilderness": "Show Wilderness", "ftbchunks.show_wilderness.just_claimed": "Show only Claimed Chunks", "tag.item.ftbchunks.right_click_blacklist": "Right Click Blacklist", @@ -304,8 +311,8 @@ "mob_category.misc": "Misc", "ftbchunks.commands.claimed": "Claimed chunks: %d", "ftbchunks.commands.unclaimed": "Unclaimed chunks: %d", - "ftbchunks.commands.force_loaded": "Force-loaded chunks: %d", - "ftbchunks.command.unloaded": "Unloaded chunks: %d", + "ftbchunks.commands.force_loaded": "Forceloaded chunks: %d", + "ftbchunks.commands.unloaded": "Un-forceloaded chunks: %d (of %d total claimed)", "ftbchunks.commands.location": "Location: %s", "ftbchunks.commands.owner": "Owner: ", "ftbchunks.commands.is_force_loaded": "Force Loaded: %s", diff --git a/common/src/main/resources/assets/integrateddynamics/ftbchunks_block_colors.json b/common/src/main/resources/assets/integrateddynamics/ftbchunks_block_colors.json new file mode 100644 index 00000000..d0abcc6b --- /dev/null +++ b/common/src/main/resources/assets/integrateddynamics/ftbchunks_block_colors.json @@ -0,0 +1,3 @@ +{ + "menril_leaves": "#76B4B8" +} \ No newline at end of file diff --git a/common/src/main/resources/ftbchunks-common.mixins.json b/common/src/main/resources/ftbchunks-common.mixins.json index 8476067b..d166fba1 100644 --- a/common/src/main/resources/ftbchunks-common.mixins.json +++ b/common/src/main/resources/ftbchunks-common.mixins.json @@ -7,11 +7,12 @@ "BiomeMixin", "BlockStateMixin", "ChunkMapMixin", - "UtilMixin" + "PistonBaseBlockMixin" ], "client": [ "ClientPacketListenerMixin", - "GuiMixin" + "GuiMixin", + "UtilMixin" ], "injectors": { "defaultRequire": 1 diff --git a/gradle.properties b/gradle.properties index d2c4b700..48c36e31 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ readable_name=FTB Chunks maven_group=dev.ftb.mods mod_author=FTB Team -mod_version=2101.1.3 +mod_version=2101.1.4 minecraft_version=1.21.1 # Deps diff --git a/neoforge/src/main/java/dev/ftb/mods/ftbchunks/neoforge/FTBChunksForge.java b/neoforge/src/main/java/dev/ftb/mods/ftbchunks/neoforge/FTBChunksForge.java index 528b1383..a821a5f8 100644 --- a/neoforge/src/main/java/dev/ftb/mods/ftbchunks/neoforge/FTBChunksForge.java +++ b/neoforge/src/main/java/dev/ftb/mods/ftbchunks/neoforge/FTBChunksForge.java @@ -7,7 +7,6 @@ import dev.ftb.mods.ftbchunks.data.ClaimedChunkManagerImpl; import dev.ftb.mods.ftblibrary.math.ChunkDimPos; import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.monster.EnderMan; import net.neoforged.bus.api.IEventBus; import net.neoforged.fml.common.Mod; import net.neoforged.neoforge.common.NeoForge;