diff options
author | alemidev <me@alemi.dev> | 2023-02-07 02:36:38 +0100 |
---|---|---|
committer | alemidev <me@alemi.dev> | 2023-02-07 02:36:38 +0100 |
commit | 6e2fec79700663001977b81584de569701cb8778 (patch) | |
tree | 7d366a42407eb10699a168d8ffd0f182ec2304c7 /src/main/java/ftbsc | |
parent | b83779f7bfb8f6ce211d550e7fbc15275fd03304 (diff) |
chore: i did it again
Diffstat (limited to 'src/main/java/ftbsc')
-rw-r--r-- | src/main/java/ftbsc/bscv/BoSCoVicino.java | 181 | ||||
-rw-r--r-- | src/main/java/ftbsc/bscv/module/HudModule.java | 47 | ||||
-rw-r--r-- | src/main/java/ftbsc/bscv/module/Module.java | 154 | ||||
-rw-r--r-- | src/main/java/ftbsc/bscv/module/QuickModule.java | 90 | ||||
-rw-r--r-- | src/main/java/ftbsc/bscv/module/hud/ActiveModules.java | 40 | ||||
-rw-r--r-- | src/main/java/ftbsc/bscv/module/hud/Coordinates.java | 37 | ||||
-rw-r--r-- | src/main/java/ftbsc/bscv/module/hud/EntityList.java | 59 | ||||
-rw-r--r-- | src/main/java/ftbsc/bscv/module/hud/InfoDisplay.java | 134 | ||||
-rw-r--r-- | src/main/java/ftbsc/bscv/module/motion/VanillaFlight.java | 108 | ||||
-rw-r--r-- | src/main/java/ftbsc/bscv/module/self/FastInteract.java | 46 | ||||
-rw-r--r-- | src/main/java/ftbsc/bscv/module/vision/Fullbright.java | 47 | ||||
-rw-r--r-- | src/main/java/ftbsc/bscv/patches/TestPatch.java | 51 | ||||
-rw-r--r-- | src/main/java/ftbsc/bscv/tools/Anchor.java | 51 | ||||
-rw-r--r-- | src/main/java/ftbsc/bscv/tools/Text.java | 89 | ||||
-rw-r--r-- | src/main/java/ftbsc/bscv/tools/Utils.java | 10 |
15 files changed, 1144 insertions, 0 deletions
diff --git a/src/main/java/ftbsc/bscv/BoSCoVicino.java b/src/main/java/ftbsc/bscv/BoSCoVicino.java new file mode 100644 index 0000000..5ea29b1 --- /dev/null +++ b/src/main/java/ftbsc/bscv/BoSCoVicino.java @@ -0,0 +1,181 @@ +package ftbsc.bscv; + +import net.minecraft.block.Block; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.ClientPlayerEntity; +import net.minecraft.command.CommandSource; +import net.minecraft.command.Commands; +import net.minecraft.util.text.StringTextComponent; +import net.minecraftforge.client.event.ClientChatEvent; +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.event.world.WorldEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.ModLoadingContext; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.config.ModConfig.Type; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.exceptions.CommandSyntaxException; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; + +import ftbsc.bscv.module.Module; +import ftbsc.bscv.module.vision.*; +import ftbsc.bscv.module.motion.*; +import ftbsc.bscv.module.self.*; +import ftbsc.bscv.module.hud.*; + +// The value here should match an entry in the META-INF/mods.toml file +@Mod("bscv") +public class BoSCoVicino { + public static String MOD_ID = "bscv"; + + // Directly reference a log4j logger. + public static final Logger LOGGER = LogManager.getLogger(); + + public static Minecraft minecraft; + + public static List<Module> mods; + + private final CommandDispatcher<CommandSource> dispatcher = new CommandDispatcher<>(); + + public static ForgeConfigSpec spec; + + public BoSCoVicino() { + // Register the setup method for modloading + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::clientSetup); + + // Store minecraft instance + BoSCoVicino.minecraft = Minecraft.getInstance(); + + // load and register mods + BoSCoVicino.mods = new ArrayList<Module>(); + + ForgeConfigSpec.Builder builder = new ForgeConfigSpec.Builder(); + + // TODO also push! + // modules cannot easily pop from their builder, but here we can't easily get + // the module name yet. We should push and pop the builder ourselves and not + // bother the modules themselves. + + BoSCoVicino.mods.add(new Fullbright(builder, this.dispatcher)); + builder.pop(); + BoSCoVicino.mods.add(new VanillaFlight(builder, this.dispatcher)); + builder.pop(); + BoSCoVicino.mods.add(new FastInteract(builder, this.dispatcher)); + builder.pop(); + BoSCoVicino.mods.add(new InfoDisplay(builder, this.dispatcher)); + builder.pop(); + BoSCoVicino.mods.add(new Coordinates(builder, this.dispatcher)); + builder.pop(); + BoSCoVicino.mods.add(new EntityList(builder, this.dispatcher)); + builder.pop(); + BoSCoVicino.mods.add(new ActiveModules(builder, this.dispatcher)); + builder.pop(); + + BoSCoVicino.spec = builder.build(); + + // register config handler + ModLoadingContext.get().registerConfig(Type.CLIENT, spec, "bscv.toml"); + + // Register ourselves for server and other game events we are interested in + MinecraftForge.EVENT_BUS.register(this); + } + + public static void log(String message) { + BoSCoVicino.minecraft.gui.getChat().addMessage(new StringTextComponent(message)); + } + + private void clientSetup(final FMLClientSetupEvent event) { + LOGGER.info("Initializing modules"); + + for (Module m : BoSCoVicino.mods) { + if (m.enabled.get()) m.enable(); + } + + // TEMPORARY! add command to regenerate suggestions + dispatcher.register( + Commands.literal("hints") + .executes(ctx -> { + ClientPlayerEntity player = BoSCoVicino.minecraft.player; + if (player != null) { + try { + Field commands = player.connection.getClass().getDeclaredField("field_195517_n"); // "commands", it's obfuscated + commands.setAccessible(true); + commands.set(player.connection, this.dispatcher); + LOGGER.info("Rebuild HINTS"); + log("> rebuilt hints"); + return 1; + } catch (NoSuchFieldException e) { + log("! no such field error"); + LOGGER.error("No such field Exception while rebuilding hints"); + return 0; + } catch (IllegalAccessException e) { + log("! illegal access error"); + LOGGER.error("Illegal Access Exception while rebuilding hints"); + return 0; + } + } else { + log("! local player is NULL"); + LOGGER.error("Local player is NULL"); + return 0; + } + }) + ); + } + + @SubscribeEvent + public void onClientChatEvent(ClientChatEvent event) { + if (event.getMessage().startsWith("/")) { + CommandSource source = BoSCoVicino.minecraft.player.createCommandSourceStack(); // TODO player could be NULL + try { + LOGGER.info(String.format("Running command %s", event.getMessage())); + this.dispatcher.execute(event.getMessage().substring(1), source); + BoSCoVicino.minecraft.gui.getChat().addRecentChat(event.getMessage()); + event.setCanceled(true); + } catch (CommandSyntaxException e) { + LOGGER.error(String.format("Syntax error in command : %s", e.toString())); + } + } + } + + @SubscribeEvent + public void onWorldLoad(WorldEvent.Load event) { + // TEMPORARY! add command to regenerate suggestions + ClientPlayerEntity player = BoSCoVicino.minecraft.player; + if (player != null) { + try { + Field commands = player.connection.getClass().getDeclaredField("field_195517_n"); // "commands", it's obfuscated + commands.setAccessible(true); + commands.set(player.connection, this.dispatcher); + LOGGER.info("Rebuild HINTS"); + log("> rebuilt hints"); + } catch (NoSuchFieldException e) { + LOGGER.error("No such field Exception while rebuilding hints"); + } catch (IllegalAccessException e) { + LOGGER.error("Illegal Access Exception while rebuilding hints"); + } + } else { + LOGGER.error("Local player is NULL"); + } + } + + // You can use EventBusSubscriber to automatically subscribe events on the contained class (this is subscribing to the MOD + // Event bus for receiving Registry Events) + @Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD) + public static class RegistryEvents { + @SubscribeEvent + public static void onBlocksRegistry(final RegistryEvent.Register<Block> blockRegistryEvent) { + // register a new block here + LOGGER.info("HELLO from Register Block"); + } + } +} diff --git a/src/main/java/ftbsc/bscv/module/HudModule.java b/src/main/java/ftbsc/bscv/module/HudModule.java new file mode 100644 index 0000000..d1f0842 --- /dev/null +++ b/src/main/java/ftbsc/bscv/module/HudModule.java @@ -0,0 +1,47 @@ +package ftbsc.bscv.module; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.DoubleArgumentType; +import com.mojang.brigadier.arguments.IntegerArgumentType; + +import ftbsc.bscv.tools.Anchor; +import net.minecraft.command.CommandSource; +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.server.command.EnumArgument; + +public abstract class HudModule extends Module { + + public final ForgeConfigSpec.ConfigValue<Integer> x; + public final ForgeConfigSpec.ConfigValue<Integer> y; + public final ForgeConfigSpec.ConfigValue<Double> scale; + public final ForgeConfigSpec.EnumValue<Anchor> anchor; + + protected HudModule(String name, ForgeConfigSpec.Builder builder, CommandDispatcher<CommandSource> dispatcher) { + super(name, Group.HUD, builder, dispatcher); + + this.x = this.option( + "x", "horizontal offset", 0, + IntegerArgumentType.integer(0), Integer.class, + builder, dispatcher + ); + + this.y = this.option( + "y", "vertical offset", 0, + IntegerArgumentType.integer(0), Integer.class, + builder, dispatcher + ); + + this.scale = this.option( + "scale", "scale of element", 1.0, + DoubleArgumentType.doubleArg(0.0), Double.class, + builder, dispatcher + ); + + this.anchor = this.optionEnum( + "anchor", "origin point for coordinates", Anchor.TOPLEFT, + EnumArgument.enumArgument(Anchor.class), Anchor.class, + builder, dispatcher + ); + } + +} diff --git a/src/main/java/ftbsc/bscv/module/Module.java b/src/main/java/ftbsc/bscv/module/Module.java new file mode 100644 index 0000000..d5ba285 --- /dev/null +++ b/src/main/java/ftbsc/bscv/module/Module.java @@ -0,0 +1,154 @@ +package ftbsc.bscv.module; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.ArgumentType; + +import ftbsc.bscv.BoSCoVicino; +import net.minecraft.command.CommandSource; +import net.minecraft.command.Commands; +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.common.MinecraftForge; + +import static ftbsc.bscv.BoSCoVicino.log; + +public abstract class Module { + public enum Group { + SELF, + HUD, + BUILD, + DEFENSE, + VISION, + MOTION, + } + + public final String name; + public final Group group; + public final ForgeConfigSpec.ConfigValue<Boolean> enabled; + + protected Module(String name, Group group, ForgeConfigSpec.Builder builder, CommandDispatcher<CommandSource> dispatcher) { + this.name = name; + this.group = group; + + builder.push(this.name.toLowerCase()); + this.enabled = builder + .comment(String.format("Enables %s", this.name)) + .define("enabled", false); + + dispatcher.register( + Commands.literal(this.name.toLowerCase()) + .then( + Commands.literal("toggle") + .executes(ctx -> { + this.toggle(); + return 1; + }) + ) + .executes(ctx -> { + log(String.format("=[ %s ]%s", this.name, this.enabled.get() ? "+" : "")); + // TODO: print all mod options! + return 1; + }) + ); + } + + + // TODO can I merge these two option into one? Maybe redo with builder pattern? + + public <T extends Enum<T>> ForgeConfigSpec.EnumValue<T> optionEnum( + String name, + String comment, + T fallback, + ArgumentType<T> argument, + Class<T> clazz, + ForgeConfigSpec.Builder builder, + CommandDispatcher<CommandSource> dispatcher + ) { + ForgeConfigSpec.EnumValue<T> conf = builder + .comment(comment) + .defineEnum(name, fallback); + + dispatcher.register( + Commands.literal(this.name.toLowerCase()) + .then( + Commands.literal(name) + .then( + Commands.argument(name, argument) + .executes( ctx -> { + T value = ctx.getArgument(name, clazz); + conf.set(value); + conf.save(); + log(String.format("> %s -> %s", String.join(".", conf.getPath()), conf.get().toString())); + return 1; + })) + .executes(ctx -> { + log(String.format("> %s: %s", String.join(".", conf.getPath()), conf.get().toString())); + return 1; + }) + ) + ); + + return conf; + } + + public <T> ForgeConfigSpec.ConfigValue<T> option( + String name, + String comment, + T fallback, + ArgumentType<T> argument, + Class<T> clazz, + ForgeConfigSpec.Builder builder, + CommandDispatcher<CommandSource> dispatcher + ) { + ForgeConfigSpec.ConfigValue<T> conf = builder + .comment(comment) + .define(name, fallback); + + dispatcher.register( + Commands.literal(this.name.toLowerCase()) + .then( + Commands.literal(name) + .then( + Commands.argument(name, argument) + .executes( ctx -> { + T value = ctx.getArgument(name, clazz); + conf.set(value); + conf.save(); + log(String.format("> %s -> %s", String.join(".", conf.getPath()), conf.get().toString())); + return 1; + })) + .executes(ctx -> { + log(String.format("> %s: %s", name, conf.get().toString())); + return 1; + }) + ) + ); + + return conf; + } + + protected void onEnabled() {} + protected void onDisabled() {} + + public final void toggle() { + if (this.enabled.get()) this.disable(); + else this.enable(); + } + + public final void enable() { + MinecraftForge.EVENT_BUS.register(this); + this.enabled.set(true); + // this.enabled.save(); + this.onEnabled(); + log(String.format("%s enabled", this.name)); + BoSCoVicino.LOGGER.info(String.format("%s enabled", this.name)); + } + + public final void disable() { + MinecraftForge.EVENT_BUS.unregister(this); + this.enabled.set(false); + // this.enabled.save(); + this.onDisabled(); + log(String.format("%s disabled", this.name)); + BoSCoVicino.LOGGER.info(String.format("%s disabled", this.name)); + } +} diff --git a/src/main/java/ftbsc/bscv/module/QuickModule.java b/src/main/java/ftbsc/bscv/module/QuickModule.java new file mode 100644 index 0000000..8eefa55 --- /dev/null +++ b/src/main/java/ftbsc/bscv/module/QuickModule.java @@ -0,0 +1,90 @@ +package ftbsc.bscv.module; + +import com.mojang.brigadier.CommandDispatcher; + +import net.minecraft.client.settings.KeyBinding; +import net.minecraft.client.util.InputMappings; +import net.minecraft.command.CommandSource; +import net.minecraftforge.client.event.InputEvent; +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.client.registry.ClientRegistry; + +import ftbsc.bscv.BoSCoVicino; + +// TODO rename +public class QuickModule extends Module { + + public static final int UNBOUND = InputMappings.UNKNOWN.getValue(); + + private class ToggleHook { + private final KeyBinding key; + private final Module mod; + private boolean debounce; + // TODO all examples show isPressed() to get a debounced value + // but it seems to be missing? making my own debounce for now + protected ToggleHook(KeyBinding key, Module mod) { + this.key = key; + this.mod = mod; + this.debounce = false; + } + + private void onInput() { + if (this.debounce) { + if (!this.key.isDown()) { + this.debounce = false; + } + } else { + if (this.key.isDown()) { + this.mod.toggle(); + this.debounce = true; + } + } + } + + @SubscribeEvent + public void onKeyPress(InputEvent.KeyInputEvent event) { this.onInput(); } + @SubscribeEvent + public void onKeyPress(InputEvent.MouseInputEvent event) { this.onInput(); } + } + + public final KeyBinding keybind; + + public QuickModule(String name, Group group, int default_key, ForgeConfigSpec.Builder builder, CommandDispatcher<CommandSource> dispatcher) { + super(name, group, builder, dispatcher); + + this.keybind = new KeyBinding(key_name(name), default_key, key_category()); + ClientRegistry.registerKeyBinding(this.keybind); + + // register a separate subclass on the hook, so that it's always listening + MinecraftForge.EVENT_BUS.register(new ToggleHook(this.keybind, this)); + + // dispatcher.register( + // Commands.literal(this.name.toLowerCase()) + // .then( + // Commands.literal("bind") + // .then( + // Commands.argument("key", StringArgumentType.word()) + // .executes( ctx -> { + // this.keybind.setKey( + // InputMappings.getKey( // TODO it's not this easy! + // StringArgumentType.getString(ctx, "key") + // ) + // ); + // return 1; + // }) + // ) + // ) + // ); + } + + private static String key_name(String name) { + return String.format("key.%s.%s", BoSCoVicino.MOD_ID, name); + } + + private static String key_category() { + return String.format("key.category.%s", BoSCoVicino.MOD_ID); + } + +} diff --git a/src/main/java/ftbsc/bscv/module/hud/ActiveModules.java b/src/main/java/ftbsc/bscv/module/hud/ActiveModules.java new file mode 100644 index 0000000..5a1d8ab --- /dev/null +++ b/src/main/java/ftbsc/bscv/module/hud/ActiveModules.java @@ -0,0 +1,40 @@ +package ftbsc.bscv.module.hud; + +import static ftbsc.bscv.tools.Text.TextBuilder; + +import com.mojang.brigadier.CommandDispatcher; + +import ftbsc.bscv.BoSCoVicino; +import net.minecraft.command.CommandSource; +import net.minecraftforge.client.event.RenderGameOverlayEvent; +import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import ftbsc.bscv.module.HudModule; +import ftbsc.bscv.module.Module; + +public class ActiveModules extends HudModule { + + public ActiveModules(ForgeConfigSpec.Builder builder, CommandDispatcher<CommandSource> dispatcher) { + super("ActiveModules", builder, dispatcher); + } + + @SubscribeEvent + public void onRenderOverlay(RenderGameOverlayEvent event) { + if (event.getType() == ElementType.TEXT) { + int offset = 0; + for (Module m : BoSCoVicino.mods) { + if (m.enabled.get() && m.group != Group.HUD) { + TextBuilder() + .txt(String.format("%s <", m.name)) + .anchor(this.anchor.get()) + .x(this.x.get()) + .y(this.y.get() + offset) + .scale(this.scale.get()) + .render(event.getMatrixStack(), event.getWindow()); + offset += BoSCoVicino.minecraft.font.lineHeight; + } + } + } + } +} diff --git a/src/main/java/ftbsc/bscv/module/hud/Coordinates.java b/src/main/java/ftbsc/bscv/module/hud/Coordinates.java new file mode 100644 index 0000000..75c88b9 --- /dev/null +++ b/src/main/java/ftbsc/bscv/module/hud/Coordinates.java @@ -0,0 +1,37 @@ +package ftbsc.bscv.module.hud; + +import com.mojang.brigadier.CommandDispatcher; + +import net.minecraft.client.Minecraft; +import net.minecraft.command.CommandSource; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraftforge.client.event.RenderGameOverlayEvent; +import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +import static ftbsc.bscv.tools.Text.TextBuilder; +import ftbsc.bscv.BoSCoVicino; +import ftbsc.bscv.module.HudModule; + +public class Coordinates extends HudModule { + + public Coordinates(ForgeConfigSpec.Builder builder, CommandDispatcher<CommandSource> dispatcher) { + super("Coordinates", builder, dispatcher); + } + + @SubscribeEvent + public void onRenderOverlay(RenderGameOverlayEvent event) { + Minecraft mc = BoSCoVicino.minecraft; + if (event.getType() == ElementType.TEXT && mc.player != null) { + Vector3d position = mc.player.position(); + TextBuilder() + .txt(String.format("[ X %.1f | %.1f Z ] %.1f Y", position.x(), position.z(), position.y())) + .anchor(this.anchor.get()) + .x(this.x.get()) + .y(this.y.get()) + .scale(this.scale.get()) + .render(event.getMatrixStack(), event.getWindow()); + } + } +} diff --git a/src/main/java/ftbsc/bscv/module/hud/EntityList.java b/src/main/java/ftbsc/bscv/module/hud/EntityList.java new file mode 100644 index 0000000..ab6707e --- /dev/null +++ b/src/main/java/ftbsc/bscv/module/hud/EntityList.java @@ -0,0 +1,59 @@ +package ftbsc.bscv.module.hud; + +import static ftbsc.bscv.tools.Text.TextBuilder; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import com.mojang.brigadier.CommandDispatcher; + +import ftbsc.bscv.BoSCoVicino; +import ftbsc.bscv.module.HudModule; +import net.minecraft.command.CommandSource; +import net.minecraft.entity.Entity; +import net.minecraftforge.client.event.RenderGameOverlayEvent; +import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +public class EntityList extends HudModule { + + public EntityList(ForgeConfigSpec.Builder builder, CommandDispatcher<CommandSource> dispatcher) { + super("EntityList", builder, dispatcher); + } + + @SubscribeEvent + public void onRenderOverlay(RenderGameOverlayEvent event) { + if (event.getType() != ElementType.TEXT) return; + + List<String> entities = new ArrayList<>(); + for (Entity e : BoSCoVicino.minecraft.level.entitiesForRendering()) { + // TODO do some filtering here? + entities.add(e.getName().getString()); + } + + List<String> uniques = new ArrayList<>(); + for (String s : entities.stream().distinct().collect(Collectors.toList())) { + int num = Collections.frequency(entities, s); + if (num > 1) { + uniques.add(String.format("%s (%d)", s, num)); + } else { + uniques.add(s); + } + } + + int offset = 0; + for (String u : uniques) { + TextBuilder() + .txt(String.format("%s", u)) + .anchor(this.anchor.get()) + .x(this.x.get()) + .y(this.y.get() + offset) + .scale(this.scale.get()) + .render(event.getMatrixStack(), event.getWindow()); + offset += BoSCoVicino.minecraft.font.lineHeight; + } + } +} diff --git a/src/main/java/ftbsc/bscv/module/hud/InfoDisplay.java b/src/main/java/ftbsc/bscv/module/hud/InfoDisplay.java new file mode 100644 index 0000000..3a6e6eb --- /dev/null +++ b/src/main/java/ftbsc/bscv/module/hud/InfoDisplay.java @@ -0,0 +1,134 @@ +package ftbsc.bscv.module.hud; + +import static ftbsc.bscv.tools.Text.TextBuilder; + +import java.util.ArrayDeque; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.BoolArgumentType; + +import ftbsc.bscv.BoSCoVicino; +import ftbsc.bscv.module.HudModule; +import net.minecraft.client.Minecraft; +import net.minecraft.command.CommandSource; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.util.text.Color; +import net.minecraft.util.text.Style; +import net.minecraftforge.client.event.RenderGameOverlayEvent; +import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.event.TickEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +public class InfoDisplay extends HudModule { + + + private Vector3d last_position = new Vector3d(0.0, 0.0, 0.0); + private double instant_speed = 0.0; + private double average_speed = 0.0; + private ArrayDeque<Double> history_speed = new ArrayDeque<>(); + + public final ForgeConfigSpec.ConfigValue<Boolean> logo; + public final ForgeConfigSpec.ConfigValue<Boolean> speed; + public final ForgeConfigSpec.ConfigValue<Boolean> time; + // public final ForgeConfigSpec.ConfigValue<Boolean> fps; + // public final ForgeConfigSpec.ConfigValue<Boolean> biome; + // public final ForgeConfigSpec.ConfigValue<Boolean> latency; + // public final ForgeConfigSpec.ConfigValue<Boolean> tps; + // public final ForgeConfigSpec.ConfigValue<Boolean> light; + // public final ForgeConfigSpec.ConfigValue<Boolean> saturation; + // public final ForgeConfigSpec.ConfigValue<Boolean> system_time; + // public final ForgeConfigSpec.ConfigValue<Boolean> damage_value; + // public final ForgeConfigSpec.ConfigValue<Boolean> effects_list; + // public final ForgeConfigSpec.ConfigValue<Boolean> item_quantity; + // public final ForgeConfigSpec.ConfigValue<Boolean> client_chunk_size; + + public InfoDisplay(ForgeConfigSpec.Builder builder, CommandDispatcher<CommandSource> dispatcher) { + super("InfoDisplay", builder, dispatcher); + + this.logo = this.option( + "logo", "show logo at top of list", true, + BoolArgumentType.bool(), Boolean.class, + builder, dispatcher + ); + + this.speed = this.option( + "speed", "show speed meter", true, + BoolArgumentType.bool(), Boolean.class, + builder, dispatcher + ); + + this.time = this.option( + "time", "show world time", true, + BoolArgumentType.bool(), Boolean.class, + builder, dispatcher + ); + } + + @SubscribeEvent + public void onTick(TickEvent.ClientTickEvent event) { + if (!this.speed.get()) return; + if (BoSCoVicino.minecraft.player != null) { + this.instant_speed = + this.last_position.distanceTo(BoSCoVicino.minecraft.player.position()); + this.last_position = BoSCoVicino.minecraft.player.position(); + } else { + this.instant_speed = 0.0; + } + + this.history_speed.push(this.instant_speed); + while (this.history_speed.size() >= 100) { // TODO customize this parameter + this.history_speed.pop(); + } + + double buf = 0.0; + for (double v : this.history_speed) { buf += v; } + this.average_speed = buf / this.history_speed.size(); + } + + @SubscribeEvent + public void onRenderOverlay(RenderGameOverlayEvent event) { + if (event.getType() != ElementType.TEXT) return; + + Minecraft mc = BoSCoVicino.minecraft; + int offset = 0; + double scale = this.scale.get(); + if (this.logo.get()) { + TextBuilder() + .txt("BSCV") + .anchor(this.anchor.get()) + .x(this.x.get() / 4) + .y(this.y.get() / 4) + .style(Style.EMPTY.withColor(Color.fromRgb(12542314)).withBold(true)) + .scale(scale * 4.0) + .render(event.getMatrixStack(), event.getWindow()); + offset += mc.font.lineHeight * scale * 4.0; + } + + if (this.time.get()) { + long daytime = 0; + if (mc.level != null) { + daytime = mc.level.dayTime(); + } + TextBuilder() + .txt(String.format("> time: %d/1200 (%d day)", (daytime / 20) % 1200, daytime / (20 * 1200) )) + .anchor(this.anchor.get()) + .x(this.x.get()) + .y(this.y.get() + offset) + .scale(scale) + .render(event.getMatrixStack(), event.getWindow()); + offset += mc.font.lineHeight * scale; + } + + if (this.speed.get()) { + TextBuilder() + .txt(String.format("> speed: %.1f [%.1f] m/s", this.instant_speed * 20.0, this.average_speed * 20.0)) + .anchor(this.anchor.get()) + .x(this.x.get()) + .y(this.y.get() + offset) + .scale(scale) + .render(event.getMatrixStack(), event.getWindow()); + offset += mc.font.lineHeight * scale; + } + } +} diff --git a/src/main/java/ftbsc/bscv/module/motion/VanillaFlight.java b/src/main/java/ftbsc/bscv/module/motion/VanillaFlight.java new file mode 100644 index 0000000..3e99f7d --- /dev/null +++ b/src/main/java/ftbsc/bscv/module/motion/VanillaFlight.java @@ -0,0 +1,108 @@ +package ftbsc.bscv.module.motion; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.BoolArgumentType; +import com.mojang.brigadier.arguments.DoubleArgumentType; +import com.mojang.brigadier.arguments.IntegerArgumentType; + +import ftbsc.bscv.BoSCoVicino; +import ftbsc.bscv.module.QuickModule; +import net.minecraft.client.entity.player.ClientPlayerEntity; +import net.minecraft.command.CommandSource; +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.event.TickEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +public class VanillaFlight extends QuickModule { + + public final ForgeConfigSpec.ConfigValue<Boolean> force; + public final ForgeConfigSpec.ConfigValue<Double> speed; + public final ForgeConfigSpec.ConfigValue<Boolean> antikick; + public final ForgeConfigSpec.ConfigValue<Double> antikick_magnitude; + public final ForgeConfigSpec.ConfigValue<Integer> antikick_cycle; + + private final float minDescent = 0.03125f; + private final int maxTicks = 80; + private int tick = 0; + + public VanillaFlight(ForgeConfigSpec.Builder builder, CommandDispatcher<CommandSource> dispatcher) { + super("VanillaFlight", Group.MOTION, UNBOUND, builder, dispatcher); + + this.force = this.option( + "force", "force enable flight on user", false, + BoolArgumentType.bool(), Boolean.class, + builder, dispatcher + ); + + this.speed = this.option( + "speed", "flight speed to set", 0.05, + DoubleArgumentType.doubleArg(0.0), Double.class, + builder, dispatcher + ); + + this.antikick = this.option( + "antikick", "prevent vanilla flight kick by descending", false, + BoolArgumentType.bool(), Boolean.class, + builder, dispatcher + ); + + this.antikick_magnitude = this.option( + "magnitude", "magnitude of antikick push", 1.0, + DoubleArgumentType.doubleArg(0.0), Double.class, + builder, dispatcher + ); + + this.antikick_cycle = this.option( + "cycle", "how often to run antikick routine", 0, + IntegerArgumentType.integer(0, 79), Integer.class, + builder, dispatcher + ); + } + + private boolean couldFlyBefore = false; + private float flyingSpeedBefore = 0.05f; + + @SubscribeEvent + public void onTick(TickEvent.ClientTickEvent event) { + ClientPlayerEntity player = BoSCoVicino.minecraft.player; + if (player == null) return; + + player.abilities.mayfly = true; + player.abilities.setFlyingSpeed(this.speed.get().floatValue()); + if (this.force.get()) { + player.abilities.flying = true; + } + if (this.antikick.get()) { + if (this.tick != 0 && this.tick % (maxTicks - this.antikick_cycle.get()) == 0) { + player.push(0.0, -(this.antikick_magnitude.get() * minDescent), 0.0); + this.tick = 0; + } else if (this.tick == 0) { + player.push(0.0, this.antikick_magnitude.get() * minDescent, 0.0); + this.tick++; + } else { + this.tick++; + } + } + } + + @Override + protected void onEnabled() { + if (BoSCoVicino.minecraft.player != null) { + this.couldFlyBefore = BoSCoVicino.minecraft.player.abilities.mayfly; + this.flyingSpeedBefore = BoSCoVicino.minecraft.player.abilities.getFlyingSpeed(); + BoSCoVicino.log(String.format("Flying speed before = %f", this.flyingSpeedBefore)); + } + } + + @Override + protected void onDisabled() { + ClientPlayerEntity player = BoSCoVicino.minecraft.player; + if (player != null) { + player.abilities.mayfly = this.couldFlyBefore; + player.abilities.setFlyingSpeed(this.flyingSpeedBefore); + if (this.force.get()) { + player.abilities.flying = false; + } + } + } +} diff --git a/src/main/java/ftbsc/bscv/module/self/FastInteract.java b/src/main/java/ftbsc/bscv/module/self/FastInteract.java new file mode 100644 index 0000000..2806ba8 --- /dev/null +++ b/src/main/java/ftbsc/bscv/module/self/FastInteract.java @@ -0,0 +1,46 @@ +package ftbsc.bscv.module.self; + +import static ftbsc.bscv.BoSCoVicino.log; + +import java.lang.reflect.Field; + +import com.mojang.brigadier.CommandDispatcher; + +import net.minecraft.command.CommandSource; +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.event.TickEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +import ftbsc.bscv.module.QuickModule; +import ftbsc.bscv.BoSCoVicino; + +public class FastInteract extends QuickModule { + + Field delayField; + + public FastInteract(ForgeConfigSpec.Builder builder, CommandDispatcher<CommandSource> dispatcher) { + super("FastInteract", Group.SELF, UNBOUND, builder, dispatcher); + } + + @Override + protected void onEnabled() { + try { + delayField = BoSCoVicino.minecraft.getClass().getDeclaredField("field_71467_ac"); + delayField.setAccessible(true); + } catch (NoSuchFieldException e) { + log("! failed accessing delay field"); + this.disable(); + } + } + + @SubscribeEvent + public void onTick(TickEvent.ClientTickEvent event) { + if (BoSCoVicino.minecraft == null) return; + try { + this.delayField.set(BoSCoVicino.minecraft, 0); + } catch (IllegalAccessException e) { + log("! failed accessing delay field"); + this.disable(); + } + } +} diff --git a/src/main/java/ftbsc/bscv/module/vision/Fullbright.java b/src/main/java/ftbsc/bscv/module/vision/Fullbright.java new file mode 100644 index 0000000..c35748e --- /dev/null +++ b/src/main/java/ftbsc/bscv/module/vision/Fullbright.java @@ -0,0 +1,47 @@ +package ftbsc.bscv.module.vision; + +import java.awt.event.KeyEvent; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.StringArgumentType; + +import net.minecraft.command.CommandSource; +import net.minecraft.potion.Effect; +import net.minecraft.potion.EffectInstance; +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.event.TickEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; + +import ftbsc.bscv.module.QuickModule; +import ftbsc.bscv.BoSCoVicino; + +public class Fullbright extends QuickModule { + + private final ForgeConfigSpec.ConfigValue<String> mode; + + public Fullbright(ForgeConfigSpec.Builder builder, CommandDispatcher<CommandSource> dispatcher) { + super("Fullbright", Group.VISION, KeyEvent.VK_V, builder, dispatcher); + + this.mode = this.option( + "mode", "either potion or potion", "potion", + StringArgumentType.string(), String.class, + builder, dispatcher + ); + } + + @SubscribeEvent + public void onTick(TickEvent.ClientTickEvent event) { + if (BoSCoVicino.minecraft == null) return; + if (BoSCoVicino.minecraft.player == null) return; + if (this.mode.get().equals("potion")) { + BoSCoVicino.minecraft.player.addEffect(new EffectInstance(Effect.byId(16), 5204)); + } + } + + @Override + protected void onDisabled() { + if (this.mode.get().equals("potion")) { + BoSCoVicino.minecraft.player.removeEffect(Effect.byId(16)); + } + } +} diff --git a/src/main/java/ftbsc/bscv/patches/TestPatch.java b/src/main/java/ftbsc/bscv/patches/TestPatch.java new file mode 100644 index 0000000..5c6c152 --- /dev/null +++ b/src/main/java/ftbsc/bscv/patches/TestPatch.java @@ -0,0 +1,51 @@ +package ftbsc.bscv.patches; + +import org.objectweb.asm.Opcodes; +import org.objectweb.asm.tree.ClassNode; +import org.objectweb.asm.tree.InsnList; +import org.objectweb.asm.tree.InsnNode; +import org.objectweb.asm.tree.MethodNode; + +import ftbsc.lll.IInjector; + +/** + * When working as intended, this patch will crash the game + * as soon it finished loading with a NegativeArraySizeException. + */ +public class TestPatch { + + public static class FramerateFix implements IInjector, Opcodes { + public String name() { return "FramerateFix"; } + public String targetClass() { return "net.minecraft.client.Minecraft"; } + public String methodName() { return "func_213243_aC"; } // getFramerateLimit() + public String methodDesc() { return "()I"; } + + public void inject(ClassNode clazz, MethodNode main) { + // InsnList insnList = new InsnList(); + // insnList.add(new InsnNode(POP)); + // main.instructions.insert(insnList); + } + } + + + public static class TickPatch implements IInjector, Opcodes { + public String name() { return "TickPatch"; } + public String targetClass() { return "net.minecraft.client.Minecraft"; } + public String methodName() { return "func_71407_l"; } // tick() + public String methodDesc() { return "()V"; } + + public void inject(ClassNode clazz, MethodNode main) { + // InsnList insnList = new InsnList(); + // insnList.add(new InsnNode(POP)); + // insnList.add(new InsnNode(POP)); + // insnList.add(new InsnNode(POP)); + // insnList.add(new InsnNode(POP)); + // insnList.add(new InsnNode(POP)); + // insnList.add(new InsnNode(POP)); + // insnList.add(new InsnNode(POP)); + // insnList.add(new InsnNode(POP)); + // main.instructions.insert(insnList); + } + } + +} diff --git a/src/main/java/ftbsc/bscv/tools/Anchor.java b/src/main/java/ftbsc/bscv/tools/Anchor.java new file mode 100644 index 0000000..29e4da7 --- /dev/null +++ b/src/main/java/ftbsc/bscv/tools/Anchor.java @@ -0,0 +1,51 @@ +package ftbsc.bscv.tools; + +import ftbsc.bscv.BoSCoVicino; +import net.minecraft.client.MainWindow; +import net.minecraft.client.gui.screen.ChatScreen; +import net.minecraft.util.math.vector.Vector2f; + +public enum Anchor { + + TOPLEFT("TOPLEFT"), TOPCENTER("TOPCENTER"), TOPRIGHT("TOPRIGHT"), + MIDDLELEFT("MIDDLELEFT"), MIDDLECENTER("MIDDLECENTER"), MIDDLERIGHT("MIDDLERIGHT"), + BOTTOMLEFT("BOTTOMLEFT"), BOTTOMCENTER("BOTTOMCENTER"), BOTTOMRIGHT("BOTTOMRIGHT"); + + private Anchor(String in) { } + + public Vector2f translate(Vector2f in, int textWidth, int lineHeight, float scale, MainWindow window) { + int offset = 0; + switch (this) { + case BOTTOMLEFT: + case BOTTOMCENTER: + case BOTTOMRIGHT: + if (BoSCoVicino.minecraft.screen instanceof ChatScreen) { + offset = 15; + } + default: + } + // TODO de-spaghetti this mess + switch (this) { + case TOPLEFT: + return new Vector2f(in.x, in.y); + case TOPCENTER: + return new Vector2f((window.getWidth() / (scale * 4.0f)) + in.x - (textWidth / 2), in.y); + case TOPRIGHT: + return new Vector2f((window.getWidth() / (scale * 2.0f)) - (in.x + textWidth), in.y); + case MIDDLELEFT: + return new Vector2f(in.x, (window.getHeight() / (scale * 4.0f)) + in.y - (lineHeight / 2)); + case MIDDLECENTER: + return new Vector2f((window.getWidth() / (scale * 4.0f)) + in.x - (textWidth / 2), (window.getHeight() / (scale * 4.0f)) + in.y - (lineHeight / 2)); + case MIDDLERIGHT: + return new Vector2f((window.getWidth() / (scale * 2.0f)) - (in.x + textWidth ), (window.getHeight() / (scale * 4.0f)) + in.y - (lineHeight / 2)); + case BOTTOMLEFT: + return new Vector2f(in.x, (window.getHeight() / (scale * 2.0f)) - (in.y + lineHeight + offset)); + case BOTTOMCENTER: + return new Vector2f((window.getWidth() / (scale * 4.0f)) + in.x - (textWidth / 2), (window.getHeight() / (scale * 2.0f)) - (in.y + lineHeight + offset)); + case BOTTOMRIGHT: + return new Vector2f((window.getWidth() / (scale * 4.0f)) - (in.x + textWidth), (window.getHeight() / (scale * 2.0f)) - (in.y + lineHeight + offset)); + default: + return new Vector2f(0.0f, 0.0f); + } + } +} diff --git a/src/main/java/ftbsc/bscv/tools/Text.java b/src/main/java/ftbsc/bscv/tools/Text.java new file mode 100644 index 0000000..c1fa746 --- /dev/null +++ b/src/main/java/ftbsc/bscv/tools/Text.java @@ -0,0 +1,89 @@ +package ftbsc.bscv.tools; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; + +import ftbsc.bscv.BoSCoVicino; +import net.minecraft.client.MainWindow; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.util.math.vector.Vector2f; +import net.minecraft.util.text.Color; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.StringTextComponent; +import net.minecraft.util.text.Style; + + +public final class Text { + String text; + Anchor anchor; + Style style; + int x; + int y; + double scale; + + private Text() { + this.text = ""; + this.anchor = Anchor.TOPLEFT; + this.style = Style.EMPTY.withColor(Color.fromRgb(16777215)); + this.x = 0; + this.y = 0; + this.scale = 1.0; + } + + public static Text TextBuilder() { + return new Text(); + } + + public Text txt(String txt) { + this.text = txt; + return this; + } + + public Text anchor(Anchor a) { + this.anchor = a; + return this; + } + + public Text style(Style in) { + this.style = in; + return this; + } + + public Text x(int x) { + this.x = x; + return this; + } + + public Text y(int y) { + this.y = y; + return this; + } + + public Text scale(double scale) { + this.scale = scale; + return this; + } + + public void render(MatrixStack stack, MainWindow window) { + FontRenderer font = BoSCoVicino.minecraft.font; + ITextComponent text = new StringTextComponent(this.text).setStyle(this.style); + Vector2f abs_coords = this.anchor.translate( + new Vector2f(this.x, this.y), + font.width(text), + font.lineHeight, + (float) this.scale, + window + ); + // TODO is there any non-deprecated way? + RenderSystem.pushMatrix(); + RenderSystem.scaled(this.scale, this.scale, this.scale); + font.drawShadow( + stack, + text, + abs_coords.x, + abs_coords.y, + 10 // ???? TODO! + ); + RenderSystem.popMatrix(); + } +} diff --git a/src/main/java/ftbsc/bscv/tools/Utils.java b/src/main/java/ftbsc/bscv/tools/Utils.java new file mode 100644 index 0000000..e9a068f --- /dev/null +++ b/src/main/java/ftbsc/bscv/tools/Utils.java @@ -0,0 +1,10 @@ +package ftbsc.bscv.tools; + +import java.util.function.Function; +import java.util.function.Supplier; + +public class Utils { + public static <I, O> O coalesce(I val, Function<I, O> f, Supplier<O> fallback) { + return val == null ? fallback.get() : f.apply(val); + } +} |