From 2dcf6bfb5a6571ee3a5a6eb24dda3eabdbff5f70 Mon Sep 17 00:00:00 2001 From: xia-mc <2052472631@qq.com> Date: Wed, 1 May 2024 15:26:05 +0800 Subject: [PATCH] Release 2.3.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复bug --- gradle.properties | 2 +- .../anticheat/modules/AirWalk.java | 53 +++++------ .../anticheat/modules/AntiFall.java | 94 +++++++++---------- .../anticheat/modules/Backtrack.java | 2 +- .../anticheat/modules/JumpReset.java | 1 - .../anticheat/modules/NoteBot.java | 31 ++++-- .../cheatdetector/anticheat/modules/Spin.java | 1 + .../anticheat/utils/EntityUtils.java | 34 +++++++ .../anticheat/utils/FakePlayer.java | 74 +++++++++------ .../anticheat/utils/LevelUtils.java | 16 ++++ .../anticheat/utils/PacketUtils.java | 3 +- .../assets/cheatdetector/lang/en_us.json | 2 +- .../assets/cheatdetector/lang/zh_cn.json | 2 +- 13 files changed, 193 insertions(+), 122 deletions(-) create mode 100644 src/main/java/top/infsky/cheatdetector/anticheat/utils/EntityUtils.java create mode 100644 src/main/java/top/infsky/cheatdetector/anticheat/utils/LevelUtils.java diff --git a/gradle.properties b/gradle.properties index 091576d..d7fa988 100644 --- a/gradle.properties +++ b/gradle.properties @@ -7,7 +7,7 @@ org.gradle.jvmargs=-Xmx1G loader_version=0.14.23 # Mod Properties - mod_version = 2.3.0 + mod_version = 2.3.1 maven_group = top.infsky archives_base_name = CheatDetector diff --git a/src/main/java/top/infsky/cheatdetector/anticheat/modules/AirWalk.java b/src/main/java/top/infsky/cheatdetector/anticheat/modules/AirWalk.java index a35aa14..2782010 100644 --- a/src/main/java/top/infsky/cheatdetector/anticheat/modules/AirWalk.java +++ b/src/main/java/top/infsky/cheatdetector/anticheat/modules/AirWalk.java @@ -7,14 +7,12 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import top.infsky.cheatdetector.anticheat.Module; -import top.infsky.cheatdetector.anticheat.TRPlayer; import top.infsky.cheatdetector.anticheat.TRSelf; +import top.infsky.cheatdetector.anticheat.utils.LevelUtils; import top.infsky.cheatdetector.anticheat.utils.PlayerMove; import top.infsky.cheatdetector.config.Advanced3Config; import top.infsky.cheatdetector.config.ModuleConfig; -import java.io.IOException; - public class AirWalk extends Module { @Getter @Nullable @@ -34,35 +32,32 @@ public AirWalk(@NotNull TRSelf player) { @Override public void _onTick() { BlockPos current; - try (ClientLevel level = TRPlayer.CLIENT.level) { - if (isDisabled()) { - if (fakeBlockPos != null && level != null) { - if (level.getBlockState(fakeBlockPos).is(Blocks.BARRIER)) - level.setBlock(fakeBlockPos, Blocks.AIR.defaultBlockState(), 3); - } - fakeBlockPos = null; - yPos = null; - return; - } - if (level == null) return; - if (yPos == null) yPos = player.fabricPlayer.getBlockY() - 1; - - current = player.fabricPlayer.blockPosition().below(); - if (Advanced3Config.airWalkSameY && fakeBlockPos != null) - current = current.atY(yPos); - if (current == fakeBlockPos) return; - - if (fakeBlockPos != null) { + ClientLevel level = LevelUtils.getClientLevel(); + if (isDisabled()) { + if (fakeBlockPos != null && level != null) { if (level.getBlockState(fakeBlockPos).is(Blocks.BARRIER)) level.setBlock(fakeBlockPos, Blocks.AIR.defaultBlockState(), 3); - fakeBlockPos = null; - } - if (level.getBlockState(current).isAir()) { - level.setBlock(current, Blocks.BARRIER.defaultBlockState(), 3); - fakeBlockPos = current; } - } catch (IOException e) { - throw new RuntimeException(e); + fakeBlockPos = null; + yPos = null; + return; + } + if (level == null) return; + if (yPos == null) yPos = player.fabricPlayer.getBlockY() - 1; + + current = player.fabricPlayer.blockPosition().below(); + if (Advanced3Config.airWalkSameY && fakeBlockPos != null) + current = current.atY(yPos); + if (current == fakeBlockPos) return; + + if (fakeBlockPos != null) { + if (level.getBlockState(fakeBlockPos).is(Blocks.BARRIER)) + level.setBlock(fakeBlockPos, Blocks.AIR.defaultBlockState(), 3); + fakeBlockPos = null; + } + if (level.getBlockState(current).isAir()) { + level.setBlock(current, Blocks.BARRIER.defaultBlockState(), 3); + fakeBlockPos = current; } if (PlayerMove.getXzSecSpeed(player.lastPos, player.currentPos) > 1.8 && Advanced3Config.airWalkAutoJump && player.currentOnGround) diff --git a/src/main/java/top/infsky/cheatdetector/anticheat/modules/AntiFall.java b/src/main/java/top/infsky/cheatdetector/anticheat/modules/AntiFall.java index d8d0faa..349329b 100644 --- a/src/main/java/top/infsky/cheatdetector/anticheat/modules/AntiFall.java +++ b/src/main/java/top/infsky/cheatdetector/anticheat/modules/AntiFall.java @@ -4,20 +4,17 @@ import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; -import net.minecraft.world.level.block.AirBlock; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.state.BlockState; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import top.infsky.cheatdetector.CheatDetector; import top.infsky.cheatdetector.anticheat.Module; -import top.infsky.cheatdetector.anticheat.TRPlayer; import top.infsky.cheatdetector.anticheat.TRSelf; +import top.infsky.cheatdetector.anticheat.utils.LevelUtils; import top.infsky.cheatdetector.config.Advanced3Config; import top.infsky.cheatdetector.config.ModuleConfig; -import java.io.IOException; - public class AntiFall extends Module { @Getter @Nullable @@ -33,63 +30,60 @@ public AntiFall(@NotNull TRSelf player) { @Override public void _onTick() { - try (ClientLevel level = TRPlayer.CLIENT.level) { - if (isDisabled()) { - if (fakeBlockPos != null && level != null) - if (level.getBlockState(fakeBlockPos).is(Blocks.BARRIER)) - level.setBlock(fakeBlockPos, Blocks.AIR.defaultBlockState(), 3); - fakeBlockPos = null; - return; - } - if (level == null) return; + ClientLevel level = LevelUtils.getClientLevel(); + if (isDisabled()) { + if (fakeBlockPos != null && level != null) + if (level.getBlockState(fakeBlockPos).is(Blocks.BARRIER)) + level.setBlock(fakeBlockPos, Blocks.AIR.defaultBlockState(), 3); + fakeBlockPos = null; + return; + } + if (level == null) return; - BlockPos current = player.fabricPlayer.blockPosition().below(); - if (!needToClutch && Advanced3Config.antiFallFastClutchOnVoid) { - boolean isVoid = true; - try { - for (int yPos = -65; yPos <= current.getY(); yPos++) { - BlockState blockState = level.getBlockState(current.atY(yPos)); - if (!blockState.isAir()) { - isVoid = false; - break; - } + BlockPos current = player.fabricPlayer.blockPosition().below(); + if (!needToClutch && Advanced3Config.antiFallFastClutchOnVoid) { + boolean isVoid = true; + try { + for (int yPos = -65; yPos <= current.getY(); yPos++) { + BlockState blockState = level.getBlockState(current.atY(yPos)); + if (!blockState.isAir()) { + isVoid = false; + break; } - } catch (Exception e) { - customMsg(e.getLocalizedMessage()); - } - if (isVoid) { - needToClutch = true; - customMsg(Component.translatable("cheatdetector.chat.alert.clutch").getString()); } + } catch (Exception e) { + customMsg(e.getLocalizedMessage()); } - if (!needToClutch && !player.fabricPlayer.isFallFlying() && player.fabricPlayer.fallDistance >= Advanced3Config.antiFallFallDistance) { + if (isVoid) { needToClutch = true; customMsg(Component.translatable("cheatdetector.chat.alert.clutch").getString()); } + } + if (!needToClutch && !player.fabricPlayer.isFallFlying() && player.fabricPlayer.fallDistance >= Advanced3Config.antiFallFallDistance) { + needToClutch = true; + customMsg(Component.translatable("cheatdetector.chat.alert.clutch").getString()); + } - if (needToClutch) { - if (player.fabricPlayer.input.shiftKeyDown && player.currentOnGround) current = current.below(); - if (current == fakeBlockPos) return; + if (needToClutch) { + if (player.fabricPlayer.input.shiftKeyDown && player.currentOnGround) current = current.below(); + if (current == fakeBlockPos) return; - if (fakeBlockPos != null) { - if (level.getBlockState(fakeBlockPos).is(Blocks.BARRIER)) - level.setBlock(fakeBlockPos, Blocks.AIR.defaultBlockState(), 3); - fakeBlockPos = null; - } - if (level.getBlockState(current).isAir()) { - level.setBlock(current, Blocks.BARRIER.defaultBlockState(), 3); - fakeBlockPos = current; - } else { - needToClutch = false; - if (Advanced3Config.antiFallClutchMsg) - customMsg(Component.translatable("cheatdetector.chat.alert.clutchDone").getString()); - if (Advanced3Config.antiFallAutoDisabled) - CheatDetector.CONFIG_HANDLER.configManager.setValue("antiFallEnabled", false); - } + if (fakeBlockPos != null) { + if (level.getBlockState(fakeBlockPos).is(Blocks.BARRIER)) + level.setBlock(fakeBlockPos, Blocks.AIR.defaultBlockState(), 3); + fakeBlockPos = null; + } + if (level.getBlockState(current).isAir()) { + level.setBlock(current, Blocks.BARRIER.defaultBlockState(), 3); + fakeBlockPos = current; + } else { + needToClutch = false; + if (Advanced3Config.antiFallClutchMsg) + customMsg(Component.translatable("cheatdetector.chat.alert.clutchDone").getString()); + if (Advanced3Config.antiFallAutoDisabled) + CheatDetector.CONFIG_HANDLER.configManager.setValue("antiFallEnabled", false); } - } catch (IOException e) { - throw new RuntimeException(e); } } diff --git a/src/main/java/top/infsky/cheatdetector/anticheat/modules/Backtrack.java b/src/main/java/top/infsky/cheatdetector/anticheat/modules/Backtrack.java index eac9ede..5e85dc1 100644 --- a/src/main/java/top/infsky/cheatdetector/anticheat/modules/Backtrack.java +++ b/src/main/java/top/infsky/cheatdetector/anticheat/modules/Backtrack.java @@ -78,7 +78,7 @@ public boolean _handleAttack(Entity entity) { if (targetVisual != null) targetVisual.hide(); targetVisual = null; - targetVisual = new FakePlayer(player.fabricPlayer.level(), target.blockPosition(), target.getGameProfile()); + targetVisual = new FakePlayer(target); targetVisual.show(); } } diff --git a/src/main/java/top/infsky/cheatdetector/anticheat/modules/JumpReset.java b/src/main/java/top/infsky/cheatdetector/anticheat/modules/JumpReset.java index 55b5b5c..4f81fa6 100644 --- a/src/main/java/top/infsky/cheatdetector/anticheat/modules/JumpReset.java +++ b/src/main/java/top/infsky/cheatdetector/anticheat/modules/JumpReset.java @@ -38,7 +38,6 @@ public void _onTick() { if (!VelocityUtils.shouldCheck(player, null)) return; if (player.lastOnGround) { - customMsg("jump!"); player.fabricPlayer.jumpFromGround(); } } diff --git a/src/main/java/top/infsky/cheatdetector/anticheat/modules/NoteBot.java b/src/main/java/top/infsky/cheatdetector/anticheat/modules/NoteBot.java index 841389a..e89be9e 100644 --- a/src/main/java/top/infsky/cheatdetector/anticheat/modules/NoteBot.java +++ b/src/main/java/top/infsky/cheatdetector/anticheat/modules/NoteBot.java @@ -10,6 +10,7 @@ import net.minecraft.network.protocol.game.ServerboundUseItemOnPacket; import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.world.InteractionHand; +import net.minecraft.world.level.Level; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.NoteBlock; import net.minecraft.world.level.block.state.BlockState; @@ -35,6 +36,8 @@ import top.infsky.cheatdetector.utils.LogUtils; import java.io.File; +import java.io.IOException; +import java.nio.file.InvalidPathException; import java.nio.file.Path; import java.util.*; import java.util.concurrent.CancellationException; @@ -78,10 +81,18 @@ public boolean isDisabled() { @Override public void _onTick() { if (!lastEnabled && !isDisabled()) { + String baseStringPath = Advanced3Config.noteBotFilePath; + String stringPath = baseStringPath.charAt(0) == '"' && baseStringPath.charAt(baseStringPath.length() - 1) == '"' ? + baseStringPath.substring(1, baseStringPath.length() - 1) : baseStringPath; + try { - loadSong(Path.of(Advanced3Config.noteBotFilePath).toFile()); + loadSong(Path.of(stringPath).toFile()); // tune(); - } catch (NullPointerException ignored) {} + } catch (NullPointerException ignored) { + } catch (InvalidPathException e) { + error("Invalid path: %s".formatted(stringPath)); + stop(); + } } else if (lastEnabled && isDisabled()) { stop(); } @@ -235,7 +246,7 @@ private void tune() { } private void tuneBlocks() { - if (TRPlayer.CLIENT.level == null || player.fabricPlayer == null) { + if (player.fabricPlayer == null) { CheatDetector.CONFIG_HANDLER.configManager.setValue("noteBotEnabled", false); ModuleConfig.noteBotEnabled = false; } @@ -486,18 +497,20 @@ private void onTickPlay() { } private void playRotate(BlockPos pos) { - if (TRPlayer.CLIENT.player == null) return; - if (TRPlayer.CLIENT.gameMode == null) return; try { - TRPlayer.CLIENT.player.connection.send(new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, pos, Direction.DOWN, 0)); + player.fabricPlayer.connection.send(new ServerboundPlayerActionPacket(ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK, pos, Direction.DOWN, 0)); } catch (NullPointerException ignored) { } } private boolean isValidScanSpot(BlockPos pos) { - if (TRPlayer.CLIENT.level == null) return false; - if (TRPlayer.CLIENT.level.getBlockState(pos).getBlock() != Blocks.NOTE_BLOCK) return false; - return TRPlayer.CLIENT.level.getBlockState(pos.above()).isAir(); + try (Level level = TRPlayer.CLIENT.level) { + if (level == null) return false; + if (level.getBlockState(pos).getBlock() != Blocks.NOTE_BLOCK) return false; + return level.getBlockState(pos.above()).isAir(); + } catch (IOException e) { + throw new RuntimeException(e); + } } /** diff --git a/src/main/java/top/infsky/cheatdetector/anticheat/modules/Spin.java b/src/main/java/top/infsky/cheatdetector/anticheat/modules/Spin.java index b54a56a..4b09d60 100644 --- a/src/main/java/top/infsky/cheatdetector/anticheat/modules/Spin.java +++ b/src/main/java/top/infsky/cheatdetector/anticheat/modules/Spin.java @@ -96,6 +96,7 @@ public void packetRot() { @Override public boolean _handleMovePlayer(@NotNull ServerboundMovePlayerPacket packet, @NotNull Connection connection, PacketSendListener listener, @NotNull CallbackInfo ci) { + if (isDisabled()) return false; if (!Advanced3Config.spinOnlyPacket) return false; return PlayerRotation.cancelRotationPacket(packet, connection, listener, ci); } diff --git a/src/main/java/top/infsky/cheatdetector/anticheat/utils/EntityUtils.java b/src/main/java/top/infsky/cheatdetector/anticheat/utils/EntityUtils.java new file mode 100644 index 0000000..9bb8148 --- /dev/null +++ b/src/main/java/top/infsky/cheatdetector/anticheat/utils/EntityUtils.java @@ -0,0 +1,34 @@ +package top.infsky.cheatdetector.anticheat.utils; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.EquipmentSlot; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.ai.attributes.*; +import net.minecraft.world.item.ItemStack; + +public class EntityUtils { + /** + * @see LivingEntity#getAttributes() + */ + public static AttributeMap getAttributes(LivingEntity entity) { + AttributeMap attributes = new AttributeMap(getDefaultForEntity(entity)); + + // Equipment + for (var equipmentSlot : EquipmentSlot.values()) { + ItemStack stack = entity.getItemBySlot(equipmentSlot); + attributes.addTransientAttributeModifiers(stack.getAttributeModifiers(equipmentSlot)); + } + + // Status effects + for (var statusEffect : entity.getActiveEffectsMap().values()) { + statusEffect.getEffect().addAttributeModifiers(entity, attributes, statusEffect.getAmplifier()); + } + + return attributes; + } + + @SuppressWarnings("unchecked") + private static AttributeSupplier getDefaultForEntity(T entity) { + return DefaultAttributes.getSupplier((EntityType) entity.getType()); + } +} diff --git a/src/main/java/top/infsky/cheatdetector/anticheat/utils/FakePlayer.java b/src/main/java/top/infsky/cheatdetector/anticheat/utils/FakePlayer.java index 1f796be..9f740f8 100644 --- a/src/main/java/top/infsky/cheatdetector/anticheat/utils/FakePlayer.java +++ b/src/main/java/top/infsky/cheatdetector/anticheat/utils/FakePlayer.java @@ -2,44 +2,64 @@ import com.mojang.authlib.GameProfile; import net.minecraft.client.multiplayer.ClientPacketListener; -import net.minecraft.core.BlockPos; +import net.minecraft.client.player.RemotePlayer; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.*; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; -import org.jetbrains.annotations.NotNull; import top.infsky.cheatdetector.anticheat.TRPlayer; import top.infsky.cheatdetector.mixins.LookAtPacketInvoker; import top.infsky.cheatdetector.utils.LogUtils; -public class FakePlayer { - @NotNull - public Player player; - - public FakePlayer(Level level, BlockPos position, GameProfile gameProfile) { - this.player = new Player(level, position, 0, gameProfile) { - @Override - public boolean isSpectator() { - return false; - } - - @Override - public boolean isCreative() { - return false; - } - }; +import java.util.UUID; + +public class FakePlayer extends RemotePlayer { + private boolean isRemoved = true; + + public FakePlayer(Player player) { + super(LevelUtils.getClientLevel(), new GameProfile(UUID.randomUUID(), player.getName().getString())); + + copyPosition(player); + + yRotO = getYRot(); + xRotO = getXRot(); + yHeadRot = player.yHeadRot; + yHeadRotO = yHeadRot; + yBodyRot = player.yBodyRot; + yBodyRotO = yBodyRot; + + Byte playerModel = player.getEntityData().get(Player.DATA_PLAYER_MODE_CUSTOMISATION); + entityData.set(Player.DATA_PLAYER_MODE_CUSTOMISATION, playerModel); + + getAttributes().assignValues(EntityUtils.getAttributes(player)); + setPose(player.getPose()); + + xCloak = getX(); + yCloak = getY(); + zCloak = getZ(); + + if (getHealth() <= 20) { + setHealth(getHealth()); + } else { + setHealth(getHealth()); + setAbsorptionAmount(getHealth() - 20); + } + + getInventory().replaceWith(player.getInventory()); + LogUtils.custom("create fakePlayer"); } public void show() { - if (TRPlayer.CLIENT.getConnection() == null) return; - TRPlayer.CLIENT.getConnection().handleAddPlayer(new ClientboundAddPlayerPacket(player)); + if (!isRemoved) return; + LevelUtils.getClientLevel().addPlayer(getId(), this); + isRemoved = false; } public void hide() { - if (TRPlayer.CLIENT.getConnection() == null) return; - TRPlayer.CLIENT.getConnection().handleRemoveEntities(new ClientboundRemoveEntitiesPacket(player.getId())); + if (isRemoved) return; + LevelUtils.getClientLevel().removeEntity(getId(), RemovalReason.DISCARDED); + isRemoved = true; } public void handlePacket(Packet basePacket) { @@ -53,12 +73,12 @@ else if (basePacket instanceof ClientboundPlayerLookAtPacket packet) { LookAtPacketInvoker packet1 = (LookAtPacketInvoker) packet; connection.handleLookAt(new ClientboundPlayerLookAtPacket(packet1.getFromAnchor(), packet1.getX(), packet1.getY(), packet1.getZ())); } else if (basePacket instanceof ClientboundDamageEventPacket packet) - connection.handleDamageEvent(new ClientboundDamageEventPacket(player, packet.getSource(player.level()))); + connection.handleDamageEvent(new ClientboundDamageEventPacket(this, packet.getSource(this.level()))); else if (basePacket instanceof ClientboundAnimatePacket packet) - connection.handleAnimate(new ClientboundAnimatePacket(player, packet.getAction())); + connection.handleAnimate(new ClientboundAnimatePacket(this, packet.getAction())); else if (basePacket instanceof ClientboundHurtAnimationPacket) - connection.handleHurtAnimation(new ClientboundHurtAnimationPacket(player)); + connection.handleHurtAnimation(new ClientboundHurtAnimationPacket(this)); else if (basePacket instanceof ClientboundSetEntityMotionPacket packet) - connection.handleSetEntityMotion(new ClientboundSetEntityMotionPacket(player.getId(), new Vec3(packet.getXa() * 8000, packet.getYa() * 8000, packet.getZa() * 8000))); + connection.handleSetEntityMotion(new ClientboundSetEntityMotionPacket(this.getId(), new Vec3(packet.getXa() * 8000, packet.getYa() * 8000, packet.getZa() * 8000))); } } diff --git a/src/main/java/top/infsky/cheatdetector/anticheat/utils/LevelUtils.java b/src/main/java/top/infsky/cheatdetector/anticheat/utils/LevelUtils.java new file mode 100644 index 0000000..d10aac4 --- /dev/null +++ b/src/main/java/top/infsky/cheatdetector/anticheat/utils/LevelUtils.java @@ -0,0 +1,16 @@ +package top.infsky.cheatdetector.anticheat.utils; + +import net.minecraft.client.multiplayer.ClientLevel; +import top.infsky.cheatdetector.anticheat.TRPlayer; + +import java.io.IOException; + +public class LevelUtils { + public static ClientLevel getClientLevel() { + try (ClientLevel level = TRPlayer.CLIENT.level) { + return level; + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/top/infsky/cheatdetector/anticheat/utils/PacketUtils.java b/src/main/java/top/infsky/cheatdetector/anticheat/utils/PacketUtils.java index b4d6ab9..75cdfb2 100644 --- a/src/main/java/top/infsky/cheatdetector/anticheat/utils/PacketUtils.java +++ b/src/main/java/top/infsky/cheatdetector/anticheat/utils/PacketUtils.java @@ -25,8 +25,7 @@ public static class Backtrack { ClientboundPlayerAbilitiesPacket.class, ClientboundKeepAlivePacket.class, ClientboundMoveEntityPacket.class, - ClientboundSetEntityMotionPacket.class, - ClientboundEntityEventPacket.class + ClientboundSetEntityMotionPacket.class ); } } diff --git a/src/main/resources/assets/cheatdetector/lang/en_us.json b/src/main/resources/assets/cheatdetector/lang/en_us.json index 22a3e1b..2d2ac5a 100644 --- a/src/main/resources/assets/cheatdetector/lang/en_us.json +++ b/src/main/resources/assets/cheatdetector/lang/en_us.json @@ -95,5 +95,5 @@ "cheatdetector.gui.button.tab.anticheat": "AntiCheat", "cheatdetector.gui.button.tab.fixes": "Fixes", "cheatdetector.gui.button.tab.modules": "Modules", - "cheatdetector.gui.title": "CheatDetector 2.3.0" + "cheatdetector.gui.title": "CheatDetector 2.3.1" } \ No newline at end of file diff --git a/src/main/resources/assets/cheatdetector/lang/zh_cn.json b/src/main/resources/assets/cheatdetector/lang/zh_cn.json index f75535e..d0c8529 100644 --- a/src/main/resources/assets/cheatdetector/lang/zh_cn.json +++ b/src/main/resources/assets/cheatdetector/lang/zh_cn.json @@ -95,5 +95,5 @@ "cheatdetector.gui.button.tab.anticheat": "反作弊", "cheatdetector.gui.button.tab.fixes": "修复", "cheatdetector.gui.button.tab.modules": "模块", - "cheatdetector.gui.title": "作弊检测器 2.3.0" + "cheatdetector.gui.title": "作弊检测器 2.3.1" } \ No newline at end of file