From a29e8920ab6cbeefe2e62e37e9181f246f90a809 Mon Sep 17 00:00:00 2001 From: 0xTas Date: Sun, 21 Jan 2024 02:02:35 -0800 Subject: [PATCH] Improved year detection for OldSigns with regex. - also fixed the ChunkPos calculation for targeted signs and added a chunk cache to reduce unnecessary computations. --- .../java/dev/stardust/modules/ChatSigns.java | 40 ++++++++++++++++--- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/src/main/java/dev/stardust/modules/ChatSigns.java b/src/main/java/dev/stardust/modules/ChatSigns.java index c18fd27..4485837 100644 --- a/src/main/java/dev/stardust/modules/ChatSigns.java +++ b/src/main/java/dev/stardust/modules/ChatSigns.java @@ -11,6 +11,8 @@ import dev.stardust.Stardust; import net.minecraft.block.*; import net.minecraft.text.Text; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import java.util.stream.Stream; import net.minecraft.text.Style; import net.minecraft.world.World; @@ -219,6 +221,9 @@ public enum RepeatMode { private final ArrayList blacklisted = new ArrayList<>(); private final HashMap cooldowns = new HashMap<>(); private final HashMap signMessages = new HashMap<>(); + private final HashMap chunkCache = new HashMap<>(); + private final Pattern fullYearsPattern = Pattern.compile("202[0-9]"); + private final Pattern truncatedYearsPattern = Pattern.compile("[0-9]*[-/.]2[0-9]"); @Nullable private BlockPos getTargetedSign() { @@ -294,8 +299,15 @@ private String formatSignText(SignBlockEntity sign, WorldChunk chunk) { if (woodType == WoodType.OAK) { NbtCompound metadata = sign.toInitialChunkDataNbt(); if (!metadata.toString().contains("{\"extra\":[{\"") && !lines.isEmpty()) { - if (lines.stream().noneMatch(line -> line.contains("2023") || line.contains("/23") || line.contains("-23"))) { - couldBeOld = !likelyNewChunk(chunk, mc, dimension); + String testString = String.join(" ", lines); + Matcher fullYearsMatcher = this.fullYearsPattern.matcher(testString); + + if (!fullYearsMatcher.find()) { + Matcher truncatedYearsMatcher = this.truncatedYearsPattern.matcher(testString); + + if (!truncatedYearsMatcher.find()) { + couldBeOld = !likelyNewChunk(chunk, mc, dimension); + } } } } @@ -338,30 +350,45 @@ private String formatSignText(SignBlockEntity sign, WorldChunk chunk) { private boolean likelyNewChunk(WorldChunk chunk, MinecraftClient mc, RegistryKey dimension) { if (mc.world == null) return false; ChunkPos chunkPos = chunk.getPos(); + if (this.chunkCache.containsKey(chunkPos)) { + return this.chunkCache.get(chunkPos); + } + if (dimension == World.NETHER) { BlockPos startPosDebris = chunkPos.getBlockPos(0, 0, 0); BlockPos endPosDebris = chunkPos.getBlockPos(15, 118, 15); int newBlocks = 0; for (BlockPos pos : BlockPos.iterate(startPosDebris, endPosDebris)) { - if (newBlocks >= 13) return true; + if (newBlocks >= 13) { + this.chunkCache.put(chunkPos, true); + return true; + } Block block = mc.world.getBlockState(pos).getBlock(); if (block == Blocks.ANCIENT_DEBRIS || block == Blocks.BLACKSTONE || block == Blocks.BASALT || block == Blocks.WARPED_NYLIUM || block == Blocks.CRIMSON_NYLIUM || block == Blocks.SOUL_SOIL) ++newBlocks; } + this.chunkCache.put(chunkPos, (newBlocks >= 13)); + return newBlocks >= 13; } else if (dimension == World.OVERWORLD){ BlockPos startPosCopper = chunkPos.getBlockPos(0, 0, 0); - BlockPos endPosCopper = chunkPos.getBlockPos(15, 63, 15); + BlockPos endPosCopper = chunkPos.getBlockPos(15, 112, 15); int newBlocks = 0; for (BlockPos pos : BlockPos.iterate(startPosCopper, endPosCopper)) { - if (newBlocks >= 13) return true; + if (newBlocks >= 13) { + this.chunkCache.put(chunkPos, true); + return true; + } Block block = mc.world.getBlockState(pos).getBlock(); if (block == Blocks.COPPER_ORE) ++newBlocks; // Copper generates in all overworld biomes except dripstone caves. else if (block == Blocks.DRIPSTONE_BLOCK || block == Blocks.POINTED_DRIPSTONE) ++newBlocks; } + this.chunkCache.put(chunkPos, (newBlocks >= 13)); + return newBlocks >= 13; }// idk what to do about the end, so we'll detect signs by default. if you don't want it, turn it off in there. + this.chunkCache.put(chunkPos, false); return false; } @@ -505,6 +532,7 @@ public void onActivate() { public void onDeactivate() { this.posSet.clear(); this.cooldowns.clear(); + this.chunkCache.clear(); this.blacklisted.clear(); this.signMessages.clear(); this.totalTicksEnabled = 0; @@ -539,7 +567,7 @@ private void onTick(TickEvent.Pre event) { if (targetedSign.equals(this.lastFocusedSign) && repeatMode.get() == RepeatMode.On_Focus) return; else if (!targetedSign.equals(this.lastFocusedSign)) this.lastFocusedSign = targetedSign; - WorldChunk chunk = mc.world.getChunk(targetedSign.getX(), targetedSign.getZ()); + WorldChunk chunk = mc.world.getChunk(targetedSign.getX() >> 4, targetedSign.getZ() >> 4); if (repeatMode.get() == RepeatMode.Cooldown) { if (cooldowns.containsKey(targetedSign)) { Instant now = Instant.now();