diff --git a/README.md b/README.md index c1d7721..2e020eb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Stardust ✨ +# ✨ Stardust Stardust is an addon for [Meteor Client](https://meteorclient.com) designed for use on the anarchy Minecraft server [2b2t](https://2b2t.org).
@@ -9,32 +9,41 @@ It contains original modules to enhance your experience on old server, with a fo - **Stats2b2t, LastSeen2b2t, FirstSeen2b2t, Playtime2b2t** - *Self explanatory commands. Use your meteor prefix.* Credit to [rfresh](https://github.com/rfresh2) for the current best [2b2t stats api](https://api.2b2t.vc). - **Panorama** - *Takes a panorama screenshot and automatically assembles it into a resource pack for the main menu screen.* Usage: `.panorama [name]` +

+ #### Modules +- **ChatSigns** - *Read nearby signs in your chat.* Can also highlight and ESP potentially old signs placed before version 1.8 (January 2015 on 2b2t.)* - **SignatureSign** - *An AutoSign module that's actually good.* Fully customizable template mode, & story mode for long input files over multiple signs. - **SignHistorian** - *Record and restore broken or modified signs that you previously visited.* Since 1.19, creepers have been a real problem for sign boards everywhere. Now even if they blow that shit up, all is not lost. -- **AxolotlTools** - *Variant ESP, auto-collector & auto-breeder for axolotls.* Can also catch buckets of tropical fish, with or without a farm setup. I used this to get blue axolotls on 2b2t because interacting with them normally pisses me off. +- **RocketMan** - *Makes flying with fireworks much easier (and faster!) \[bring lots of rockets!\]* RocketMan is a versatile and highly-configurable firework efly module with many useful capabilities. +- **StashBrander** - *Automatically rename desired items in bulk when using anvils.* - **AutoDoors** - *Automatically interacts with doors.* Includes an insufferable door spammer mode as well (complete with client-side mute option). - **AutoSmith** - *Automatically upgrades gear or trims armor sets when interacting with smithing tables.* - **AntiToS** - *Censors player-generated text on render, like signs, books, chat, and more, according to a customizable content blacklist.* +- **LoreLocator** - *Slot highlighter for rare, unique, and anomalous items.* Capable of highlighting renamed items, items with illegal enchants, zero durability items, and more. +- **AxolotlTools** - *Variant ESP, auto-collector & auto-breeder for axolotls.* Can also catch buckets of tropical fish, with or without a farm setup. I used this to get blue axolotls on 2b2t because interacting with them normally pisses me off. - **AutoDrawDistance** - *Automatically adjusts your render distance to maintain an FPS target.* Some biomes/areas can drop my fps by half, so I occasionally find this useful. - **AutoDyeShulkers** - *Automatically dye shulker boxes a desired color in crafting grids.* -- **LoreLocator** - *Slot highlighter for rare, unique, and anomalous items.* Capable of highlighting renamed items, items with illegal enchants, zero durability items, and more. - **BannerData** - *Right-click banners to display their pattern and color data.* Looks cool, gives you the base color without any fuss. Can also copy the raw nbt to your clipboard. - **BookTools** - *Enhancements for working with books.* Adds buttons for inserting color & formatting codes into writable books, and adds a deobfuscation button to written books containing obfuscated/magic text. -- **StashBrander** - *Automatically rename desired items in bulk when using anvils.* - **PagePirate** - *Pirates books held by other players* (displays their contents in your chat, and optionally makes a local copy using a book & quill). - **TreasureESP** - *An ESP module for buried treasure chests.* Finding buried treasure is the only way of obtaining Hearts of the Sea, and Conduits by extension. -- **MusicTweaks** - *Lets you tweak various things relating to the background music.* Change the pitch, volume, or cooldown between songs, or even choose and view which soundtracks play during your session. -- **RocketMan** - *Makes flying with fireworks much easier (and faster!) \[bring lots of rockets!\]* RocketMan is a versatile and highly-configurable firework efly module with many useful capabilities. +- **MusicTweaks** - *Lets you tweak various things relating to the background music.* Change the pitch, volume, or cooldown between songs, or even choose and view which soundtracks play during your session. - **Honker** - *Automatically uses goat horns when a player enters your render distance.* You can select your preferred horn type, or choose random for a surprise pick from your inventory each time. - **Updraft** - *Automatically enhances your jumps with wind charges.* Wind charges seem to be nerfed on Paper compared to Vanilla, but maybe someone would still find this fun or useful. - **WaxAura** - *Automatically waxes signs within your reach.* On 2b2t, sign editing has been disabled "for now™". This module makes it easy to wax as many signs as possible before it gets enabled. -- **ChatSigns** - *Read nearby signs in your chat.* Can also highlight and ESP potentially old signs placed before version 1.8 (January 2015 on 2b2t.)* +

+ +#### Miscellaneous +- **Illegal Disconnect** - *Adds "Illegal Disconnect" functionality to Meteor's built-in AutoLog module.* Enable this in the AutoLog module's settings. Also adds a config setting to put a dedicated Illegal Disconnect button on the pause menu. +- **Title Screen Tweaks** - *2b2t-themed changes to the title screen.* Adds config settings to make the splash texts green, to cycle them randomly, and to add a 2b2t direct-connect button to the title screen. +- **Themed Category Icons** - *Enable module category icons in your config settings to see a random Stardust/2b2t-themed icon for the Stardust modules category.* Randomly picks a new icon each time you open your game! >*OldSigns:
Ever since 2b2t updated to 1.19, the NBT tag artifact that separates pre-1.8 from post-1.8 signs is missing on newly-placed signs.
This means that false positives are now *unavoidable*, but should be limited to *oak signs placed after 1.19 in old (pre-1.8) chunks that do not contain dates after 2015*.
-Use your best judgement to further identify false positives or fakes. +Use your best judgement to further identify false positives or fakes.
+OldSigns functionality can be accessed in the ChatSigns module settings.
### Installation @@ -54,8 +63,7 @@ Use your best judgement to further identify false positives or fakes. 5. Select the appropriate sources Jar from the list (usually named something like `net.minecraft:minecraft-merged-...-sources.jar`) and hit `Ok`. 6. Now you can contribute or modify code with those mappings as a reference (ctrl+click to view the source for any class.) ->Issues and pull requests are welcome if you would like to submit them.
-If needed, you can get in touch with me through the [Meteor Client Discord Server](https://discord.com/invite/bBGQZvd). +>Issues and pull requests are welcome if you would like to submit them.
### Credits diff --git a/src/main/java/dev/stardust/Stardust.java b/src/main/java/dev/stardust/Stardust.java index 587cb50..c4595ee 100644 --- a/src/main/java/dev/stardust/Stardust.java +++ b/src/main/java/dev/stardust/Stardust.java @@ -13,7 +13,10 @@ import meteordevelopment.meteorclient.commands.Commands; import meteordevelopment.meteorclient.addons.MeteorAddon; import meteordevelopment.meteorclient.settings.BoolSetting; +import meteordevelopment.meteorclient.settings.EnumSetting; import meteordevelopment.meteorclient.systems.config.Config; +import meteordevelopment.meteorclient.settings.SettingGroup; +import dev.stardust.util.StardustUtil.IllegalDisconnectMethod; import meteordevelopment.meteorclient.systems.modules.Modules; import meteordevelopment.meteorclient.systems.modules.Category; @@ -26,6 +29,8 @@ public class Stardust extends MeteorAddon { public static Setting greenSplashTextSetting = new BoolSetting.Builder().build(); public static Setting rotateSplashTextSetting = new BoolSetting.Builder().build(); public static Setting directConnectButtonSetting = new BoolSetting.Builder().build(); + public static Setting illegalDisconnectButtonSetting = new BoolSetting.Builder().build(); + public static Setting illegalDisconnectMethodSetting = new EnumSetting.Builder().defaultValue(IllegalDisconnectMethod.Slot).build(); @Override public void onInitialize() { @@ -55,30 +60,46 @@ public void onInitialize() { Modules.get().add(new SignHistorian()); Modules.get().add(new AutoDyeShulkers()); Modules.get().add(new AutoDrawDistance()); + SettingGroup sgStardust = Config.get().settings.createGroup("Stardust"); // See SplashTextRendererMixin.java - greenSplashTextSetting = Config.get().settings.getGroup("Visual").add( + greenSplashTextSetting = sgStardust.add( new BoolSetting.Builder() - .name("Green Splash Text") + .name("green-splash-text") .description(">Makes the title splash texts green.") .defaultValue(false) .build() ); // See TitleScreenMixin.java - rotateSplashTextSetting = Config.get().settings.getGroup("Visual").add( + rotateSplashTextSetting = sgStardust.add( new BoolSetting.Builder() - .name("Rotate Splash Text") + .name("rotate-splash-text") .description("Picks a new random splash text every 20 seconds.") .defaultValue(false) .build() ); - directConnectButtonSetting = Config.get().settings.getGroup("Visual").add( + directConnectButtonSetting = sgStardust.add( new BoolSetting.Builder() - .name("Direct Connect Button") + .name("direct-connect-button") .description("Adds a button to the main menu that directly connects you to 2b2t.org") .defaultValue(false) .build() ); + // See GameMenuScreenMixin.java + illegalDisconnectButtonSetting = sgStardust.add( + new BoolSetting.Builder() + .name("illegal-disconnect-button") + .description("Adds a button to the main menu that forces the server to kick you when pressed.") + .defaultValue(false) + .build() + ); + illegalDisconnectMethodSetting = sgStardust.add( + new EnumSetting.Builder() + .name("illegal-disconnect-method") + .description("The method to use to cause the server to kick you.") + .defaultValue(IllegalDisconnectMethod.Slot) + .build() + ); LOG.info("<✨> Stardust initialized."); } diff --git a/src/main/java/dev/stardust/mixin/AutoLogMixin.java b/src/main/java/dev/stardust/mixin/AutoLogMixin.java new file mode 100644 index 0000000..e79478c --- /dev/null +++ b/src/main/java/dev/stardust/mixin/AutoLogMixin.java @@ -0,0 +1,99 @@ +package dev.stardust.mixin; + +import dev.stardust.Stardust; +import net.minecraft.text.Text; +import javax.annotation.Nullable; +import dev.stardust.util.StardustUtil; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import meteordevelopment.orbit.EventHandler; +import org.spongepowered.asm.mixin.injection.At; +import meteordevelopment.meteorclient.utils.Utils; +import meteordevelopment.meteorclient.MeteorClient; +import org.spongepowered.asm.mixin.injection.Inject; +import meteordevelopment.meteorclient.settings.Setting; +import meteordevelopment.meteorclient.settings.BoolSetting; +import meteordevelopment.meteorclient.settings.SettingGroup; +import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.systems.modules.Category; +import meteordevelopment.meteorclient.events.packets.PacketEvent; +import meteordevelopment.meteorclient.systems.modules.misc.AutoLog; +import net.minecraft.network.packet.s2c.common.DisconnectS2CPacket; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +/** + * @author Tas [0xTas] + * + * Adds "Illegal Disconnect" functionality to Meteor's built-in AutoLog module. + **/ +@Mixin(value = AutoLog.class, remap = false) +public abstract class AutoLogMixin extends Module { + public AutoLogMixin(Category category, String name, String description) { + super(category, name, description); + MeteorClient.EVENT_BUS.subscribe(this); // TODO: sus + } + + @Shadow + @Final + private SettingGroup sgGeneral; + @Shadow + @Final + private Setting toggleOff; + + @Unique + private boolean didLog = false; + @Unique + @Nullable + private Text disconnectReason = null; + @Unique + @Nullable + private Setting forceKick = null; + + @Override + public void onDeactivate() { + if (toggleOff.get() && didLog) { + MeteorClient.EVENT_BUS.subscribe(this); + } + } + + @Inject(method = "", at = @At(value = "FIELD", target = "Lmeteordevelopment/meteorclient/systems/modules/misc/AutoLog;entities:Lmeteordevelopment/meteorclient/settings/Setting;")) + private void addIllegalDisconnectSetting(CallbackInfo ci) { + forceKick = sgGeneral.add( + new BoolSetting.Builder() + .name("illegal-disconnect") + .description("Tip: Change the illegal disconnect method in your Meteor config settings (Stardust category.)") + .defaultValue(false) + .build() + ); + } + + @Inject(method = "onTick",at = @At("HEAD"), cancellable = true) + private void preventNullPointerExceptions(CallbackInfo ci) { + if (!Utils.canUpdate()) ci.cancel(); + } + + @Inject(method = "disconnect", at = @At("HEAD"), cancellable = true) + private void maybeForceKick(String reason, CallbackInfo ci) { + if (forceKick != null && forceKick.get()) { + ci.cancel(); + didLog = true; + if (toggleOff.get()) toggle(); + disconnectReason = Text.literal("§8[§aAutoLog§8] §f" + reason); + StardustUtil.illegalDisconnect(true, Stardust.illegalDisconnectMethodSetting.get()); + } + } + + @Unique + @EventHandler + private void onPacketReceive(PacketEvent.Receive event) { + if (disconnectReason == null || !(event.packet instanceof DisconnectS2CPacket packet)) return; + if (didLog) { + ((DisconnectS2CPacketAccessor)(Object) packet).setReason(disconnectReason); + MeteorClient.EVENT_BUS.unsubscribe(this); + disconnectReason = null; + didLog = false; + } + } +} diff --git a/src/main/java/dev/stardust/mixin/ClientConnectionAccessor.java b/src/main/java/dev/stardust/mixin/ClientConnectionAccessor.java new file mode 100644 index 0000000..97d3a99 --- /dev/null +++ b/src/main/java/dev/stardust/mixin/ClientConnectionAccessor.java @@ -0,0 +1,14 @@ +package dev.stardust.mixin; + +import javax.annotation.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import net.minecraft.network.packet.Packet; +import net.minecraft.network.PacketCallbacks; +import net.minecraft.network.ClientConnection; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(ClientConnection.class) +public interface ClientConnectionAccessor { + @Invoker("sendImmediately") + void invokeSendImmediately(Packet packet, @Nullable PacketCallbacks callbacks, boolean flush); +} diff --git a/src/main/java/dev/stardust/mixin/DisconnectS2CPacketAccessor.java b/src/main/java/dev/stardust/mixin/DisconnectS2CPacketAccessor.java new file mode 100644 index 0000000..2b6146d --- /dev/null +++ b/src/main/java/dev/stardust/mixin/DisconnectS2CPacketAccessor.java @@ -0,0 +1,14 @@ +package dev.stardust.mixin; + +import net.minecraft.text.Text; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.gen.Accessor; +import net.minecraft.network.packet.s2c.common.DisconnectS2CPacket; + +@Mixin(DisconnectS2CPacket.class) +public interface DisconnectS2CPacketAccessor { + @Mutable + @Accessor("reason") + void setReason(Text reason); +} diff --git a/src/main/java/dev/stardust/mixin/GameMenuScreenMixin.java b/src/main/java/dev/stardust/mixin/GameMenuScreenMixin.java new file mode 100644 index 0000000..36cbc93 --- /dev/null +++ b/src/main/java/dev/stardust/mixin/GameMenuScreenMixin.java @@ -0,0 +1,35 @@ +package dev.stardust.mixin; + +import dev.stardust.Stardust; +import net.minecraft.text.Text; +import dev.stardust.util.StardustUtil; +import org.spongepowered.asm.mixin.Mixin; +import com.llamalad7.mixinextras.sugar.Local; +import net.minecraft.client.gui.screen.Screen; +import org.spongepowered.asm.mixin.injection.At; +import net.minecraft.client.gui.widget.GridWidget; +import org.spongepowered.asm.mixin.injection.Inject; +import net.minecraft.client.gui.widget.ButtonWidget; +import net.minecraft.client.gui.screen.GameMenuScreen; +import static meteordevelopment.meteorclient.MeteorClient.mc; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +/** + * @author Tas [0xTas] + **/ +@Mixin(GameMenuScreen.class) +public class GameMenuScreenMixin extends Screen { + protected GameMenuScreenMixin(Text title) { + super(title); + } + + @Inject(method = "initWidgets", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/GridWidget;refreshPositions()V")) + private void addIllegalDisconnectButton(CallbackInfo ci, @Local GridWidget.Adder adder) { + if (Stardust.illegalDisconnectButtonSetting.get() && !mc.isInSingleplayer()) { + adder.add(ButtonWidget.builder(Text.literal("§cIllegal Disconnect"), button -> { + button.active = false; + StardustUtil.illegalDisconnect(false, Stardust.illegalDisconnectMethodSetting.get()); + }).width(204).build(), 2); + } + } +} diff --git a/src/main/java/dev/stardust/util/StardustUtil.java b/src/main/java/dev/stardust/util/StardustUtil.java index 405f58d..8e922a0 100644 --- a/src/main/java/dev/stardust/util/StardustUtil.java +++ b/src/main/java/dev/stardust/util/StardustUtil.java @@ -1,17 +1,30 @@ package dev.stardust.util; import java.io.File; +import java.time.Instant; import dev.stardust.Stardust; +import net.minecraft.util.Hand; import net.minecraft.text.Text; import net.minecraft.text.Style; import net.minecraft.item.Items; import net.minecraft.item.ItemStack; import net.minecraft.text.ClickEvent; import net.minecraft.text.MutableText; +import net.minecraft.network.packet.Packet; import net.fabricmc.loader.api.FabricLoader; import net.minecraft.client.MinecraftClient; +import net.minecraft.network.packet.c2s.play.*; import io.netty.util.internal.ThreadLocalRandom; +import meteordevelopment.meteorclient.utils.Utils; import net.minecraft.component.DataComponentTypes; +import dev.stardust.mixin.ClientConnectionAccessor; +import static meteordevelopment.meteorclient.MeteorClient.mc; +import meteordevelopment.meteorclient.systems.modules.Modules; +import net.minecraft.network.encryption.NetworkEncryptionUtils; +import net.minecraft.network.packet.c2s.common.SyncedClientOptions; +import net.minecraft.network.packet.c2s.common.ClientOptionsC2SPacket; +import meteordevelopment.meteorclient.systems.modules.misc.AutoReconnect; +import meteordevelopment.meteorclient.mixin.ClientPlayNetworkHandlerAccessor; /** * @author Tas [@0xTas] @@ -243,8 +256,48 @@ public static void openFile(MinecraftClient mc, String fileName) { runtime.exec(new String[]{"xdg-open", file.getAbsolutePath()}); } } catch (Exception err) { - Stardust.LOG.error("[Stardust] Failed to open "+ file.getAbsolutePath() +"! - Why:\n"+err); + Stardust.LOG.error("Failed to open "+ file.getAbsolutePath() +"! - Why:\n"+err); if (mc.player != null) mc.player.sendMessage(Text.of("§8<"+StardustUtil.rCC()+"✨§8> §4§oFailed to open "+file.getName()+"§7.")); } } + + public enum IllegalDisconnectMethod { + Slot, Chat, Interact, Movement, SequenceBreak, InvalidSettings + } + + public static void illegalDisconnect(boolean disableAutoReconnect, IllegalDisconnectMethod illegalDisconnectMethod) { + if (!Utils.canUpdate()) return; + if (disableAutoReconnect) disableAutoReconnect(); + + Packet illegalPacket = null; + switch (illegalDisconnectMethod) { + case Slot -> illegalPacket = new UpdateSelectedSlotC2SPacket(-69); + case Chat -> illegalPacket = new ChatMessageC2SPacket( + "§", + Instant.now(), + NetworkEncryptionUtils.SecureRandomUtil.nextLong(), + null, + ((ClientPlayNetworkHandlerAccessor) mc.getNetworkHandler()).getLastSeenMessagesCollector().collect().update() + ); + case Interact -> illegalPacket = PlayerInteractEntityC2SPacket.interact(mc.player, false, Hand.MAIN_HAND); + case Movement -> illegalPacket = new PlayerMoveC2SPacket.PositionAndOnGround(Double.NaN, 69, Double.NaN, false); + case SequenceBreak -> illegalPacket = new PlayerInteractItemC2SPacket(Hand.MAIN_HAND, -420, 13.37F, 69.69F); + case InvalidSettings -> illegalPacket = new ClientOptionsC2SPacket(new SyncedClientOptions( + mc.options.language, -69, + mc.options.getChatVisibility().getValue(), mc.options.getChatColors().getValue(), + mc.options.getSyncedOptions().playerModelParts(), mc.options.getMainArm().getValue(), + mc.options.getSyncedOptions().filtersText(), mc.options.getAllowServerListing().getValue() + )); + } + if (illegalPacket != null) ((ClientConnectionAccessor) mc.getNetworkHandler().getConnection()).invokeSendImmediately( + illegalPacket, null, true + ); + } + + public static void disableAutoReconnect() { + Modules mods = Modules.get(); + if (mods == null) return; + AutoReconnect atrc = mods.get(AutoReconnect.class); + if (atrc.isActive()) atrc.toggle(); + } } diff --git a/src/main/resources/stardust.mixins.json b/src/main/resources/stardust.mixins.json index e19e676..65475f8 100644 --- a/src/main/resources/stardust.mixins.json +++ b/src/main/resources/stardust.mixins.json @@ -13,6 +13,7 @@ "SoundSystemMixin", "TitleScreenMixin", "MusicTrackerMixin", + "GameMenuScreenMixin", "EntityRendererMixin", "AnvilScreenAccessor", "BookEditScreenMixin", @@ -37,13 +38,16 @@ "mixins": [ "WorldMixin", "EntityMixin", + "AutoLogMixin", "ItemStackMixin", "DoorBlockMixin", "PlayerEntityMixin", "GoatHornItemMixin", "LivingEntityMixin", + "ClientConnectionAccessor", "FireworkRocketEntityMixin", "AnvilScreenHandlerAccessor", + "DisconnectS2CPacketAccessor", "PlayerMoveC2SPacketAccessor", "FireworkRocketEntityAccessor" ]