diff --git a/build.gradle b/build.gradle index 50aa708..63a7a04 100644 --- a/build.gradle +++ b/build.gradle @@ -21,7 +21,7 @@ dependencies { // Fabric API. This is technically optional, but you probably want it anyway. modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" - modImplementation include("net.kyori:adventure-platform-fabric:5.8.0") // still works on 1.20.1 + modImplementation include("net.kyori:adventure-platform-fabric:5.10.0") // for Minecraft 1.20.2 modImplementation include("net.kyori:adventure-text-serializer-legacy:4.14.0") diff --git a/gradle.properties b/gradle.properties index ac9f900..cc5cf35 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,9 +4,9 @@ org.gradle.parallel=true # Fabric Properties # check these on https://fabricmc.net/develop - minecraft_version=1.20.1 - yarn_mappings=1.20.1+build.9 - loader_version=0.14.21 + minecraft_version=1.20.2 + yarn_mappings=1.20.2+build.1 + loader_version=0.14.22 # Mod Properties mod_version = 1.0.1 @@ -14,5 +14,5 @@ org.gradle.parallel=true archives_base_name = chipmunkmod # Dependencies - fabric_version=0.84.0+1.20.1 + fabric_version=0.89.2+1.20.2 diff --git a/src/main/java/land/chipmunk/chipmunkmod/Configuration.java b/src/main/java/land/chipmunk/chipmunkmod/Configuration.java index 9b584c5..8256100 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/Configuration.java +++ b/src/main/java/land/chipmunk/chipmunkmod/Configuration.java @@ -33,7 +33,7 @@ public class Configuration { public BotInfo sbot = new BotInfo(":", null); public BotInfo ubot = new BotInfo("\"", null); public BotInfo chipmunk = new BotInfo("'", null); - public ChomeNSBotInfo chomens = new ChomeNSBotInfo("*", null, null); + public ChomeNSBotInfo chomens = new ChomeNSBotInfo("*", null, null, null); public BotInfo kittycorp = new BotInfo("^", null); public TestBotInfo testbot = new TestBotInfo("-", null); } @@ -42,11 +42,13 @@ public class Configuration { public String prefix; public String key; public String authKey; + public String formatKey; - public ChomeNSBotInfo (String prefix, String key, String authKey) { + public ChomeNSBotInfo (String prefix, String key, String authKey, String formatKey) { this.prefix = prefix; this.key = key; this.authKey = authKey; + this.formatKey = formatKey; } } diff --git a/src/main/java/land/chipmunk/chipmunkmod/commands/UsernameCommand.java b/src/main/java/land/chipmunk/chipmunkmod/commands/UsernameCommand.java index 391eb67..205625d 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/commands/UsernameCommand.java +++ b/src/main/java/land/chipmunk/chipmunkmod/commands/UsernameCommand.java @@ -14,13 +14,15 @@ import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.ConnectScreen; import net.minecraft.client.gui.screen.TitleScreen; -import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen; import net.minecraft.client.network.ServerInfo; import net.minecraft.client.network.ServerAddress; -import net.minecraft.client.util.Session; +import net.minecraft.client.session.Session; import net.minecraft.text.Text; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import java.util.Optional; +import java.util.UUID; + import land.chipmunk.chipmunkmod.mixin.MinecraftClientAccessor; public class UsernameCommand { @@ -42,7 +44,8 @@ public class UsernameCommand { public static int updateUsername (CommandContext context) throws CommandSyntaxException { final String username = getString(context, "username"); if (username.length() > 16) throw USERNAME_TOO_LONG.create(); - return updateSession(context, username); + final Session session = new Session(username, new UUID(0L, 0L), "", Optional.empty(), Optional.empty(), Session.AccountType.MOJANG); + return updateSession(context, session); } public static int updateSession (CommandContext context, String username) throws CommandSyntaxException { diff --git a/src/main/java/land/chipmunk/chipmunkmod/data/ChomeNSBotCommand.java b/src/main/java/land/chipmunk/chipmunkmod/data/ChomeNSBotCommand.java index 978e705..93a671f 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/data/ChomeNSBotCommand.java +++ b/src/main/java/land/chipmunk/chipmunkmod/data/ChomeNSBotCommand.java @@ -1,8 +1,12 @@ package land.chipmunk.chipmunkmod.data; +import java.util.ArrayList; +import java.util.List; + public class ChomeNSBotCommand { public final String name; public final TrustLevel trustLevel; + public final List aliases = new ArrayList<>(); public ChomeNSBotCommand ( String name, diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorMixin.java index eef285a..7531b9e 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorMixin.java @@ -6,11 +6,11 @@ import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import land.chipmunk.chipmunkmod.ChipmunkMod; import land.chipmunk.chipmunkmod.command.CommandManager; -import land.chipmunk.chipmunkmod.data.ChomeNSBotCommand; import land.chipmunk.chipmunkmod.modules.ChomeNSBotCommandSuggestions; import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.widget.TextFieldWidget; +import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.command.CommandSource; import org.spongepowered.asm.mixin.Final; @@ -29,10 +29,6 @@ public class ChatInputSuggestorMixin { @Shadow private CompletableFuture pendingSuggestions; - @Final - @Shadow - private boolean slashOptional; - @Shadow public void show (boolean narrateFirstSuggestion) {} @@ -52,8 +48,6 @@ public class ChatInputSuggestorMixin { @Inject(at = @At("TAIL"), method = "refresh()V") public void refresh (CallbackInfo ci) { - if (slashOptional) return; - final CommandManager commandManager = CommandManager.INSTANCE; final String text = this.textField.getText(); @@ -84,20 +78,21 @@ public class ChatInputSuggestorMixin { show(true); }); + } else if (cursor > commandManager.prefix.length() && text.startsWith(commandManager.prefix)) { + final StringReader reader = new StringReader(text); + reader.setCursor(commandManager.prefix.length()); // Skip the prefix - return; + final MinecraftClient client = MinecraftClient.getInstance(); + + final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler(); + + if (networkHandler == null) return; + + final CommandDispatcher dispatcher = commandManager.dispatcher; + final FabricClientCommandSource commandSource = (FabricClientCommandSource) networkHandler.getCommandSource(); + + pendingSuggestions = dispatcher.getCompletionSuggestions(dispatcher.parse(reader, commandSource), cursor); + show(true); } - - if (cursor < commandManager.prefix.length() || !text.startsWith(commandManager.prefix)) return; - - final StringReader reader = new StringReader(text); - reader.setCursor(commandManager.prefix.length()); // Skip the prefix - - final CommandDispatcher dispatcher = commandManager.dispatcher; - final MinecraftClient client = MinecraftClient.getInstance(); - final FabricClientCommandSource commandSource = (FabricClientCommandSource) client.getNetworkHandler().getCommandSource(); - - pendingSuggestions = dispatcher.getCompletionSuggestions(dispatcher.parse(reader, commandSource), cursor); - show(true); } } diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatScreenMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatScreenMixin.java index 1ae2d90..ecc9b95 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatScreenMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatScreenMixin.java @@ -26,42 +26,17 @@ import javax.net.ssl.HttpsURLConnection; import java.io.IOException; import java.io.OutputStream; import java.net.URL; +import java.util.ArrayList; import java.util.List; @Mixin(value = net.minecraft.client.gui.screen.ChatScreen.class) public class ChatScreenMixin extends Screen { - @Shadow protected TextFieldWidget chatField; @Shadow private String originalChatText; - @Shadow ChatInputSuggestor chatInputSuggestor; - @Shadow private int messageHistorySize = -1; - public ChatScreenMixin(String originalChatText) { - super(Text.translatable("chat_screen.title")); - this.originalChatText = originalChatText; - } - - @Inject(at = @At("TAIL"), method = "init", cancellable = true) - public void init (CallbackInfo ci) { - final MinecraftClient client = MinecraftClient.getInstance(); - - this.messageHistorySize = client.inGameHud.getChatHud().getMessageHistory().size(); - this.chatField = new TextFieldWidget(client.advanceValidatingTextRenderer, 4, this.height - 12, this.width - 4, 12, Text.translatable("chat.editBox")) { - protected MutableText getNarrationMessage() { - return super.getNarrationMessage().append(ChatScreenMixin.this.chatInputSuggestor.getNarration()); - } - }; - this.chatField.setMaxLength(Integer.MAX_VALUE); - this.chatField.setDrawsBackground(false); - this.chatField.setText(this.originalChatText); - this.chatField.setChangedListener(this::onChatFieldUpdate); - this.chatField.setFocusUnlocked(false); - this.addSelectableChild(this.chatField); - this.chatInputSuggestor = new ChatInputSuggestor(this.client, this, this.chatField, this.textRenderer, false, false, 1, 10, true, -805306368); - this.chatInputSuggestor.refresh(); - this.setInitialFocus(this.chatField); - - ci.cancel(); - } + public ChatScreenMixin(String originalChatText) { + super(Text.translatable("chat_screen.title")); + this.originalChatText = originalChatText; + } @Inject(at = @At("HEAD"), method = "sendMessage", cancellable = true) public void sendMessage(String chatText, boolean addToHistory, CallbackInfoReturnable cir) { @@ -87,9 +62,23 @@ public class ChatScreenMixin extends Screen { .map((command) -> command.name.toLowerCase()) .toList(); - if (moreOrTrustedCommands.contains(chatText.toLowerCase().split("\\s")[0])) { + final List aliases = new ArrayList<>(); + for (ChomeNSBotCommand command : commands) { + if (command.trustLevel == ChomeNSBotCommand.TrustLevel.PUBLIC) continue; + + aliases.addAll(command.aliases); + } + + final String chatCommand = chatText.toLowerCase().split("\\s")[0]; + + final int prefixLength = ChipmunkMod.CONFIG.bots.chomens.prefix.length(); + + if ( + moreOrTrustedCommands.contains(chatCommand) || + aliases.contains(chatCommand.substring(prefixLength)) + ) { try { - BotValidationUtilities.chomens(chatText.substring(ChipmunkMod.CONFIG.bots.chomens.prefix.length())); + BotValidationUtilities.chomens(chatText.substring(prefixLength)); cir.setReturnValue(true); cir.cancel(); @@ -99,6 +88,8 @@ public class ChatScreenMixin extends Screen { } } + if (client == null) return; + if (chatText.startsWith("/")) { client.player.networkHandler.sendChatCommand(chatText.substring(1)); } else { @@ -109,11 +100,4 @@ public class ChatScreenMixin extends Screen { cir.cancel(); } - - @Unique - private void onChatFieldUpdate(String chatText) { - String string = this.chatField.getText(); - this.chatInputSuggestor.setWindowActive(!string.equals(this.originalChatText)); - this.chatInputSuggestor.refresh(); - } } diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerAccessor.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerAccessor.java index 6608a03..c01f236 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerAccessor.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerAccessor.java @@ -16,9 +16,6 @@ public interface ClientPlayNetworkHandlerAccessor { @Accessor("CHAT_VALIDATION_FAILED_TEXT") static Text chatValidationFailedText () { throw new AssertionError(); } - @Accessor("connection") - ClientConnection connection(); - @Accessor("playerListEntries") Map playerListEntries(); diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java index 1da9e9f..e5d6c84 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java @@ -1,6 +1,5 @@ package land.chipmunk.chipmunkmod.mixin; -import com.mojang.authlib.GameProfile; import land.chipmunk.chipmunkmod.ChipmunkMod; import land.chipmunk.chipmunkmod.command.CommandManager; import land.chipmunk.chipmunkmod.listeners.Listener; @@ -8,26 +7,21 @@ import land.chipmunk.chipmunkmod.listeners.ListenerManager; import land.chipmunk.chipmunkmod.modules.*; import net.kyori.adventure.text.TextComponent; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.gui.screen.Screen; -import net.minecraft.client.network.ClientDynamicRegistryType; -import net.minecraft.client.network.ServerInfo; -import net.minecraft.client.util.telemetry.WorldSession; import net.minecraft.command.CommandRegistryAccess; -import net.minecraft.network.ClientConnection; import net.minecraft.network.encryption.NetworkEncryptionUtils; import net.minecraft.network.message.LastSeenMessagesCollector; import net.minecraft.network.message.MessageBody; import net.minecraft.network.message.MessageChain; import net.minecraft.network.message.MessageSignatureData; -import net.minecraft.network.packet.Packet; import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket; import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket; import net.minecraft.network.packet.s2c.play.GameMessageS2CPacket; import net.minecraft.network.packet.s2c.play.PlayerRemoveS2CPacket; -import net.minecraft.registry.CombinedDynamicRegistries; +import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.resource.featuretoggle.FeatureSet; import net.minecraft.text.Text; import net.minecraft.text.TranslatableTextContent; +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; @@ -38,22 +32,16 @@ import java.time.Instant; @Mixin(value = net.minecraft.client.network.ClientPlayNetworkHandler.class, priority = 1001) public class ClientPlayNetworkHandlerMixin { + @Final @Shadow private FeatureSet enabledFeatures; - @Shadow private CombinedDynamicRegistries combinedDynamicRegistries; + @Final + @Shadow private DynamicRegistryManager.Immutable combinedDynamicRegistries; @Shadow private LastSeenMessagesCollector lastSeenMessagesCollector; @Shadow private MessageChain.Packer messagePacker; - @Shadow - public void sendPacket(Packet packet) {} - - @Inject(method = "", at = @At("TAIL")) - private void init (MinecraftClient client, Screen screen, ClientConnection connection, ServerInfo serverInfo, GameProfile profile, WorldSession worldSession, CallbackInfo ci) { - - } - @Inject(method = "onGameJoin", at = @At("TAIL")) private void onGameJoin (GameJoinS2CPacket packet, CallbackInfo ci) { - final CommandRegistryAccess commandRegistryAccess = CommandRegistryAccess.of(this.combinedDynamicRegistries.getCombinedRegistryManager(), this.enabledFeatures); + final CommandRegistryAccess commandRegistryAccess = CommandRegistryAccess.of(this.combinedDynamicRegistries, this.enabledFeatures); KaboomCheck.INSTANCE.onJoin(); CommandManager.INSTANCE = new CommandManager(ChipmunkMod.CONFIG.commands.prefix, commandRegistryAccess); @@ -63,12 +51,12 @@ public class ClientPlayNetworkHandlerMixin { RainbowName.INSTANCE.init(); ChomeNSBotCommandSuggestions.INSTANCE.init(); ChomeNSAuth.INSTANCE.init(); + CustomChat.INSTANCE.init(); } @Inject(method = "onPlayerRemove", at = @At("HEAD"), cancellable = true) private void onPlayerRemove (PlayerRemoveS2CPacket packet, CallbackInfo ci) { ci.cancel(); } - @Inject(method = "onGameMessage", at = @At("HEAD"), cancellable = true) private void onGameMessage (GameMessageS2CPacket packet, CallbackInfo ci) { final Text message = packet.content(); @@ -128,7 +116,7 @@ public class ClientPlayNetworkHandlerMixin { long l = NetworkEncryptionUtils.SecureRandomUtil.nextLong(); LastSeenMessagesCollector.LastSeenMessages lastSeenMessages = this.lastSeenMessagesCollector.collect(); MessageSignatureData messageSignatureData = this.messagePacker.pack(new MessageBody(content, instant, l, lastSeenMessages.lastSeen())); - this.sendPacket(new ChatMessageC2SPacket(content, instant, l, messageSignatureData, lastSeenMessages.update())); + MinecraftClient.getInstance().getNetworkHandler().sendPacket(new ChatMessageC2SPacket(content, instant, l, messageSignatureData, lastSeenMessages.update())); ci.cancel(); } diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayerEntityMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayerEntityMixin.java index 5e21818..9f406e0 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayerEntityMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayerEntityMixin.java @@ -30,6 +30,9 @@ public class ClientPlayerEntityMixin { final BlockPos origin = CommandCore.INSTANCE.origin; if (origin == null) { CommandCore.INSTANCE.move(position); return; } final int distance = (int) Math.sqrt(new Vec2f(origin.getX() / 16, origin.getZ() / 16).distanceSquared(new Vec2f((int) position.getX() / 16, (int) position.getZ() / 16))); - if (distance > world.getSimulationDistance()) CommandCore.INSTANCE.move(position); + if (distance > world.getSimulationDistance()) { + CommandCore.INSTANCE.clientPlayerEntityFilled = true; + CommandCore.INSTANCE.move(position); + } } } diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/DecoderHandlerMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/DecoderHandlerMixin.java deleted file mode 100644 index 687ae6c..0000000 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/DecoderHandlerMixin.java +++ /dev/null @@ -1,46 +0,0 @@ -package land.chipmunk.chipmunkmod.mixin; - -import io.netty.buffer.ByteBuf; -import io.netty.channel.ChannelHandlerContext; -import net.minecraft.network.*; -import net.minecraft.network.packet.Packet; -import net.minecraft.util.profiling.jfr.FlightProfiler; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Mutable; -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 java.util.List; - -import static land.chipmunk.chipmunkmod.ChipmunkMod.LOGGER; - -@Mixin(DecoderHandler.class) -public class DecoderHandlerMixin { - @Final @Mutable @Shadow private final NetworkSide side; - - public DecoderHandlerMixin(NetworkSide side) { - this.side = side; - } - - @Inject(method = "decode", at = @At("HEAD"), cancellable = true) - private void decode (ChannelHandlerContext ctx, ByteBuf buf, List objects, CallbackInfo ci) { - int i = buf.readableBytes(); - if (i != 0) { - PacketByteBuf packetByteBuf = new PacketByteBuf(buf); - int j = packetByteBuf.readVarInt(); - Packet packet = ctx.channel().attr(ClientConnection.PROTOCOL_ATTRIBUTE_KEY).get().getPacketHandler(this.side, j, packetByteBuf); - if (packet != null) { - int k = ctx.channel().attr(ClientConnection.PROTOCOL_ATTRIBUTE_KEY).get().getId(); - FlightProfiler.INSTANCE.onPacketReceived(k, j, ctx.channel().remoteAddress(), i); - objects.add(packet); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(ClientConnection.PACKET_RECEIVED_MARKER, " IN: [{}:{}] {}", ctx.channel().attr(ClientConnection.PROTOCOL_ATTRIBUTE_KEY).get(), j, packet.getClass().getName()); - } - } - } - ci.cancel(); - } -} diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/DecoratedPotBlockEntitySherdsMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/DecoratedPotBlockEntitySherdsMixin.java index cb5b5ac..f38b4bf 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/DecoratedPotBlockEntitySherdsMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/DecoratedPotBlockEntitySherdsMixin.java @@ -15,7 +15,7 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture; // https://github.com/LunaWasFlaggedAgain/Mojang-ResourceLocation-Challenge/blob/main/src/main/java/com/github/lunawasflaggedagain/mojangresourcelocationchallenge/mixin/DecoratedPotBlockEntitySherdsMixin.java @Mixin(DecoratedPotBlockEntity.Sherds.class) public class DecoratedPotBlockEntitySherdsMixin { - @Inject(method = "getSherd(Lnet/minecraft/nbt/NbtList;I)Lnet/minecraft/item/Item;", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Identifier;(Ljava/lang/String;)V"), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true) + @Inject(method = "getSherd", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Identifier;tryParse(Ljava/lang/String;)Lnet/minecraft/util/Identifier;"), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true) private static void getSherd(NbtList list, int index, CallbackInfoReturnable cir, NbtElement nbtElement) { if (!Identifier.isValid(nbtElement.asString())) cir.setReturnValue(Items.BRICK); } diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/MinecraftClientAccessor.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/MinecraftClientAccessor.java index 4a45e34..04f2cb8 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/MinecraftClientAccessor.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/MinecraftClientAccessor.java @@ -1,9 +1,9 @@ package land.chipmunk.chipmunkmod.mixin; +import net.minecraft.client.session.Session; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mutable; import org.spongepowered.asm.mixin.gen.Accessor; -import net.minecraft.client.util.Session; @Mixin(net.minecraft.client.MinecraftClient.class) public interface MinecraftClientAccessor { diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/TextFieldWidgetMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/TextFieldWidgetMixin.java new file mode 100644 index 0000000..c56b682 --- /dev/null +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/TextFieldWidgetMixin.java @@ -0,0 +1,20 @@ +package land.chipmunk.chipmunkmod.mixin; + +import net.minecraft.client.gui.widget.TextFieldWidget; +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; + +@Mixin(TextFieldWidget.class) +public class TextFieldWidgetMixin { + @Shadow private int maxLength; + + @Inject(method = "setMaxLength", at = @At("HEAD"), cancellable = true) + private void setMaxLength (int length, CallbackInfo ci) { + this.maxLength = Integer.MAX_VALUE; + + ci.cancel(); + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/modules/ChomeNSAuth.java b/src/main/java/land/chipmunk/chipmunkmod/modules/ChomeNSAuth.java index 5579c15..264ea4d 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/modules/ChomeNSAuth.java +++ b/src/main/java/land/chipmunk/chipmunkmod/modules/ChomeNSAuth.java @@ -70,6 +70,10 @@ public class ChomeNSAuth extends Listener { final String toSendString = GsonComponentSerializer.gson().serialize(toSend); + System.out.println("Sending " + toSendString + " to " + selector); + CommandCore.INSTANCE.run("tellraw " + selector + " " + toSendString); + + CustomChat.INSTANCE.resetTotal(); } } diff --git a/src/main/java/land/chipmunk/chipmunkmod/modules/ChomeNSBotCommandSuggestions.java b/src/main/java/land/chipmunk/chipmunkmod/modules/ChomeNSBotCommandSuggestions.java index 32a28b2..91bd70c 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/modules/ChomeNSBotCommandSuggestions.java +++ b/src/main/java/land/chipmunk/chipmunkmod/modules/ChomeNSBotCommandSuggestions.java @@ -13,7 +13,6 @@ import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.text.Text; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; public class ChomeNSBotCommandSuggestions extends Listener { @@ -59,7 +58,7 @@ public class ChomeNSBotCommandSuggestions extends Listener { final List children = component.children(); - if (children.size() == 0) return; + if (children.isEmpty()) return; final TextComponent textComponent = (TextComponent) children.get(0); @@ -68,10 +67,24 @@ public class ChomeNSBotCommandSuggestions extends Listener { commands = children.subList(1, children.size()) .stream() .map( - (eachCum) -> new ChomeNSBotCommand( - ChipmunkMod.CONFIG.bots.chomens.prefix + ((TextComponent) eachCum).content(), - ChomeNSBotCommand.TrustLevel.valueOf(((TextComponent) eachCum.children().get(0)).content()) - ) + (eachComponent) -> { + final ChomeNSBotCommand command = new ChomeNSBotCommand( + ChipmunkMod.CONFIG.bots.chomens.prefix + ((TextComponent) eachComponent).content(), + ChomeNSBotCommand.TrustLevel.valueOf(((TextComponent) eachComponent.children().get(0)).content()) + ); + + if (!Boolean.parseBoolean(((TextComponent) eachComponent.children().get(1)).content())) return command; + + final List subList = eachComponent.children().subList(2, eachComponent.children().size()); + + for (Component aliasComponent : subList) { + final String alias = ((TextComponent) aliasComponent).content(); + + command.aliases.add(alias); + } + + return command; + } ) .toList(); } catch (Exception ignored) {} diff --git a/src/main/java/land/chipmunk/chipmunkmod/modules/CommandCore.java b/src/main/java/land/chipmunk/chipmunkmod/modules/CommandCore.java index e4e6db9..37b3771 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/modules/CommandCore.java +++ b/src/main/java/land/chipmunk/chipmunkmod/modules/CommandCore.java @@ -5,6 +5,8 @@ import land.chipmunk.chipmunkmod.data.BlockArea; import land.chipmunk.chipmunkmod.listeners.Listener; import land.chipmunk.chipmunkmod.listeners.ListenerManager; import land.chipmunk.chipmunkmod.util.MathUtilities; +import net.minecraft.block.Block; +import net.minecraft.block.CommandBlock; import net.minecraft.block.entity.CommandBlockBlockEntity; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayNetworkHandler; @@ -30,8 +32,12 @@ public class CommandCore { private Timer timer; + private boolean shouldRefill = false; + public boolean runFillCommand = true; + public boolean clientPlayerEntityFilled = false; + public static CommandCore INSTANCE = new CommandCore(MinecraftClient.getInstance()); public CommandCore (MinecraftClient client) { @@ -40,10 +46,7 @@ public class CommandCore { } public void init () { - if (timer != null) { - cleanup(); - return; - } + if (timer != null) cleanup(); final TimerTask task = new TimerTask() { public void run () { @@ -51,15 +54,41 @@ public class CommandCore { } }; + final TimerTask refillTask = new TimerTask() { + @Override + public void run() { + if (clientPlayerEntityFilled) { + clientPlayerEntityFilled = false; + return; + } + + check(); + + if (!shouldRefill) return; + + refill(); + + shouldRefill = false; + } + }; + timer = new Timer(); timer.schedule(task, 50, 50); + + timer.schedule(refillTask, 50, 1000); + + move(client.player.getPos()); } private void tick () { final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler(); - if (networkHandler == null) cleanup(); + if (networkHandler == null) { + cleanup(); + + return; + } reloadRelativeArea(); } @@ -68,6 +97,36 @@ public class CommandCore { noPos = ChipmunkMod.CONFIG.core.relativeArea; } + public void check () { + final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler(); + + if (networkHandler == null || withPos == null || !ready) return; + + try { + for (int x = withPos.start.getX(); x <= withPos.end.getX(); x++) { + for (int y = withPos.start.getY(); y <= withPos.end.getY(); y++) { + for (int z = withPos.start.getZ(); z <= withPos.end.getZ(); z++) { + final BlockPos pos = new BlockPos(x, y, z); + + final ClientWorld world = client.world; + + if (world == null) return; + + final Block block = world.getBlockState(pos).getBlock(); + + if (block instanceof CommandBlock) continue; + + shouldRefill = true; + + return; + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + public void move (Vec3d position) { final ClientWorld world = client.world; @@ -162,6 +221,8 @@ public class CommandCore { if (block == null) return; + System.out.println(command); + if (KaboomCheck.INSTANCE.isKaboom) { connection.send( new UpdateCommandBlockC2SPacket( diff --git a/src/main/java/land/chipmunk/chipmunkmod/modules/CustomChat.java b/src/main/java/land/chipmunk/chipmunkmod/modules/CustomChat.java index 443bc91..083ccf4 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/modules/CustomChat.java +++ b/src/main/java/land/chipmunk/chipmunkmod/modules/CustomChat.java @@ -1,10 +1,10 @@ package land.chipmunk.chipmunkmod.modules; +import com.google.common.hash.Hashing; import com.google.gson.JsonElement; import land.chipmunk.chipmunkmod.ChipmunkMod; -import land.chipmunk.chipmunkmod.commands.SayCommand; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; @@ -14,6 +14,9 @@ import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.text.Text; +import java.nio.charset.StandardCharsets; +import java.util.Timer; +import java.util.TimerTask; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -26,12 +29,49 @@ public class CustomChat { public String format; + private Timer timer; + + private int total = 0; + public CustomChat (MinecraftClient client) { this.client = client; reloadFormat(); } + public void init () { + final TimerTask task = new TimerTask() { + public void run () { + tick(); + } + }; + + resetTotal(); + + timer = new Timer(); + timer.schedule(task, 0, 50); + } + + private void tick () { + final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler(); + + if (networkHandler != null) return; + + resetTotal(); + cleanup(); + } + + public void resetTotal() { + total = 0; + } + + private void cleanup () { + if (timer == null) return; + + timer.cancel(); + timer.purge(); + } + public void reloadFormat () { final JsonElement formatString = ChipmunkMod.CONFIG.customChat.format; @@ -60,6 +100,17 @@ public class CustomChat { final Component deserialized = serializer.deserialize(message); final String messageWithColor = GsonComponentSerializer.gson().serialize(deserialized).replace("MESSAGE", randomized); + final String key = ChipmunkMod.CONFIG.bots.chomens.formatKey; + + final String hash = key != null ? + Hashing.sha256() + .hashString(key + total, StandardCharsets.UTF_8) + .toString() + .substring(0, 8) : + ""; + + total++; + try { // final MutablePlayerListEntry entry = Players.INSTANCE.getEntry(client.getNetworkHandler().getProfile().getId()); @@ -73,9 +124,10 @@ public class CustomChat { // .replace("\"PREFIX\"", prefix) // .replace("\"DISPLAYNAME\"", displayName) .replace("USERNAME", username) + .replace("HASH", hash) .replace("{\"text\":\"MESSAGE\"}", messageWithColor) .replace("\"extra\":[\"MESSAGE\"],\"color\":", "\"extra\":[" + messageWithColor + "],\"color\":") - .replace("MESSAGE", sanitizedMessage.replaceAll("&.", "")) // TODO: make this not use regex + .replace("MESSAGE", sanitizedMessage.replaceAll("&.", "")) .replace(randomized, "MESSAGE"); // ohio ohio CommandCore.INSTANCE.run((KaboomCheck.INSTANCE.isKaboom ? "minecraft:tellraw @a " : "tellraw @a ") + sanitizedFormat); diff --git a/src/main/java/land/chipmunk/chipmunkmod/modules/KaboomCheck.java b/src/main/java/land/chipmunk/chipmunkmod/modules/KaboomCheck.java index 8bbdb12..877bcfe 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/modules/KaboomCheck.java +++ b/src/main/java/land/chipmunk/chipmunkmod/modules/KaboomCheck.java @@ -1,28 +1,20 @@ package land.chipmunk.chipmunkmod.modules; +import com.mojang.brigadier.suggestion.Suggestion; +import com.mojang.brigadier.suggestion.Suggestions; import land.chipmunk.chipmunkmod.listeners.Listener; import land.chipmunk.chipmunkmod.listeners.ListenerManager; - import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.network.packet.Packet; -import net.minecraft.network.packet.s2c.play.SubtitleS2CPacket; -import net.minecraft.network.packet.s2c.play.TitleS2CPacket; +import net.minecraft.network.packet.s2c.play.CommandSuggestionsS2CPacket; import java.util.Timer; import java.util.TimerTask; +import java.util.concurrent.CompletableFuture; public class KaboomCheck extends Listener { - public static final String TITLE_START_TEXT = "Welcome to "; - public static final String TITLE_END_TEXT = "!"; - - public static final String SUBTITLE_START_TEXT = "Free OP"; - public boolean isKaboom = false; - private boolean hasKaboomTitle = false; - private boolean hasKaboomSubtitle = false; - private Timer timer = null; private final MinecraftClient client; @@ -49,50 +41,43 @@ public class KaboomCheck extends Listener { timer = new Timer(); timer.schedule(task, 50, 50); + + check(); } private void tick () { final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler(); if (networkHandler == null) cleanup(); + } - if (hasKaboomTitle && hasKaboomSubtitle) isKaboom = true; + private void check () { + final CompletableFuture future = TabComplete.INSTANCE.complete("/ver "); + + future.thenApply((packet) -> { + final Suggestions suggestions = packet.getSuggestions(); + + for (int i = 0; i < suggestions.getList().size(); i++) { + final Suggestion suggestion = suggestions.getList().get(i); + + if (suggestion.getText().equals("Extras")) { + isKaboom = true; + break; + } + } + + return packet; + }); } private void cleanup () { if (timer == null) return; isKaboom = false; - hasKaboomTitle = false; - hasKaboomSubtitle = false; timer.purge(); timer.cancel(); } - @Override - public void packetReceived(Packet packet) { - if (packet instanceof TitleS2CPacket) packetReceived((TitleS2CPacket) packet); - else if (packet instanceof SubtitleS2CPacket) packetReceived((SubtitleS2CPacket) packet); - } - // TODO: move this to a util class - private String stripSectionSigns (String text) { - return text.replaceAll("ยง.", ""); - } - - public void packetReceived(TitleS2CPacket packet) { - final String stripped = stripSectionSigns(packet.getTitle().getString()); - - if ( - stripped.startsWith(TITLE_START_TEXT) && - stripped.endsWith(TITLE_END_TEXT) - ) hasKaboomTitle = true; - } - - public void packetReceived(SubtitleS2CPacket packet) { - final String stripped = stripSectionSigns(packet.getSubtitle().getString()); - - if (stripped.startsWith(SUBTITLE_START_TEXT)) hasKaboomSubtitle = true; - } } diff --git a/src/main/java/land/chipmunk/chipmunkmod/modules/SelfCare.java b/src/main/java/land/chipmunk/chipmunkmod/modules/SelfCare.java index 34a1aa9..e22210e 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/modules/SelfCare.java +++ b/src/main/java/land/chipmunk/chipmunkmod/modules/SelfCare.java @@ -136,7 +136,7 @@ public class SelfCare extends Listener { } public void packetReceived(GameJoinS2CPacket packet) { - gameMode = packet.gameMode().getId(); + gameMode = packet.commonPlayerSpawnInfo().gameMode().getId(); } public void packetReceived(GameStateChangeS2CPacket packet) { diff --git a/src/main/java/land/chipmunk/chipmunkmod/modules/SongPlayer.java b/src/main/java/land/chipmunk/chipmunkmod/modules/SongPlayer.java index efac249..7605f92 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/modules/SongPlayer.java +++ b/src/main/java/land/chipmunk/chipmunkmod/modules/SongPlayer.java @@ -1,28 +1,20 @@ package land.chipmunk.chipmunkmod.modules; -import land.chipmunk.chipmunkmod.mixin.ClientConnectionAccessor; -import land.chipmunk.chipmunkmod.mixin.ClientConnectionInvoker; -import land.chipmunk.chipmunkmod.mixin.ClientPlayNetworkHandlerAccessor; import land.chipmunk.chipmunkmod.song.Note; import land.chipmunk.chipmunkmod.song.Song; import land.chipmunk.chipmunkmod.song.SongLoaderException; import land.chipmunk.chipmunkmod.song.SongLoaderThread; import land.chipmunk.chipmunkmod.util.MathUtilities; - - import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket; -import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.sound.SoundCategory; import net.minecraft.sound.SoundEvent; import net.minecraft.text.Text; import net.minecraft.util.Identifier; -import net.minecraft.util.math.random.Random; import java.io.File; import java.net.URL; @@ -222,23 +214,16 @@ public class SongPlayer { if (thing[1] == null) return; // idk if this can be null but ill just protect it for now i guess - final ClientPlayNetworkHandlerAccessor networkHandlerAccessor = (ClientPlayNetworkHandlerAccessor) client.getNetworkHandler(); - - final ClientConnectionAccessor clientConnectionAccessor = (ClientConnectionAccessor) networkHandlerAccessor.connection(); - - ClientConnectionInvoker.handlePacket( - new PlaySoundS2CPacket( - RegistryEntry.of(SoundEvent.of(Identifier.of(thing[0], thing[1]))), - SoundCategory.RECORDS, - client.player.getX(), - client.player.getY(), - client.player.getZ(), - note.volume, - floatingPitch, - Random.create().nextLong() - ), - clientConnectionAccessor.packetListener() - ); + client.submit(() -> client.world.playSound( + client.player.getX(), + client.player.getY(), + client.player.getZ(), + SoundEvent.of(Identifier.of(thing[0], thing[1])), + SoundCategory.RECORDS, + note.volume, + floatingPitch, + true + )); } else { final float floatingPitch = MathUtilities.clamp((float) (0.5 * (Math.pow(2, ((note.pitch + (pitch / 10)) / 12)))), 0F, 2F); diff --git a/src/main/java/land/chipmunk/chipmunkmod/util/BotValidationUtilities.java b/src/main/java/land/chipmunk/chipmunkmod/util/BotValidationUtilities.java index dce1e12..070659f 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/util/BotValidationUtilities.java +++ b/src/main/java/land/chipmunk/chipmunkmod/util/BotValidationUtilities.java @@ -29,7 +29,7 @@ public class BotValidationUtilities { try { MessageDigest md = MessageDigest.getInstance("SHA-256"); String time = String.valueOf(System.currentTimeMillis() / 10000); - String input = command.replaceAll("&[0-9a-fklmnor]", "") + ";" + client.player.getUuidAsString() + ";" + time + ";" + key; + String input = prefix + command.replaceAll("&[0-9a-fklmnor]", "") + ";" + client.player.getUuidAsString() + ";" + time + ";" + key; byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8)); BigInteger bigInt = new BigInteger(1, Arrays.copyOfRange(hash, 0, 4)); String stringHash = bigInt.toString(Character.MAX_RADIX); diff --git a/src/main/resources/chipmunkmod.mixins.json b/src/main/resources/chipmunkmod.mixins.json index d782698..a9f226f 100644 --- a/src/main/resources/chipmunkmod.mixins.json +++ b/src/main/resources/chipmunkmod.mixins.json @@ -15,6 +15,8 @@ "ClientPlayNetworkHandlerMixin", "DecoderHandlerMixin", "DecoratedPotBlockEntitySherdsMixin", + "MinecraftClientAccessor", + "StringHelperMixin", "ElderGuardianAppearanceParticleMixin", "FontStorageMixin", "IdentifierMixin", @@ -28,7 +30,11 @@ "SharedConstantsMixin", "StringHelperMixin", "TextMixin", - "TitleScreenMixin" + "TitleScreenMixin", + "TextSerializerMixin", + "CommandDispatcherMixin", + "SoundSystemMixin", + "TextFieldWidgetMixin" ], "injectors": { "defaultRequire": 1 diff --git a/src/main/resources/default_config.json b/src/main/resources/default_config.json index 865d631..27ee095 100644 --- a/src/main/resources/default_config.json +++ b/src/main/resources/default_config.json @@ -15,7 +15,7 @@ "sbot": { "prefix": ":", "key": null }, "ubot": { "prefix": "\"", "key": null }, "chipmunk": { "prefix": "'", "key": null }, - "chomens": { "prefix": "*", "key": null, "authKey": null }, + "chomens": { "prefix": "*", "key": null, "authKey": null, "formatKey": null }, "kittycorp": { "prefix": "^", "key": null }, "testbot": { "prefix": "-", "webhookUrl": null } },