From 88dc82eb1e755848a934af940283250f301e6efd Mon Sep 17 00:00:00 2001 From: Chipmunk <65827213+ChipmunkMC@users.noreply.github.com> Date: Sat, 11 Mar 2023 21:56:16 -0500 Subject: [PATCH] Config support can prob be improved but that will be done later :trollface: --- .../chipmunk/chipmunkmod/ChipmunkMod.java | 85 +++-- .../chipmunk/chipmunkmod/Configuration.java | 17 + .../chipmunkmod/command/CommandManager.java | 145 ++++----- .../chipmunkmod/commands/CoreCommand.java | 158 +++++----- .../chipmunkmod/commands/TestCommand.java | 48 +-- .../chipmunkmod/commands/UsernameCommand.java | 134 ++++---- .../chipmunk/chipmunkmod/data/BlockArea.java | 26 +- .../mixin/ChatInputSuggestorMixin.java | 100 +++--- .../chipmunkmod/mixin/ChatScreenMixin.java | 44 +-- .../mixin/ClientConnectionMixin.java | 40 +-- .../ClientPlayNetworkHandlerAccessor.java | 22 +- .../mixin/ClientPlayNetworkHandlerMixin.java | 32 +- .../mixin/ClientPlayerEntityMixin.java | 68 ++-- .../mixin/MinecraftClientAccessor.java | 32 +- .../chipmunkmod/modules/CommandCore.java | 295 +++++++++--------- .../chipmunkmod/modules/SelfCare.java | 144 ++++----- src/main/resources/default_config.json | 12 + 17 files changed, 738 insertions(+), 664 deletions(-) mode change 100644 => 100755 src/main/java/land/chipmunk/chipmunkmod/ChipmunkMod.java create mode 100755 src/main/java/land/chipmunk/chipmunkmod/Configuration.java mode change 100644 => 100755 src/main/java/land/chipmunk/chipmunkmod/command/CommandManager.java mode change 100644 => 100755 src/main/java/land/chipmunk/chipmunkmod/commands/CoreCommand.java mode change 100644 => 100755 src/main/java/land/chipmunk/chipmunkmod/commands/TestCommand.java mode change 100644 => 100755 src/main/java/land/chipmunk/chipmunkmod/commands/UsernameCommand.java mode change 100644 => 100755 src/main/java/land/chipmunk/chipmunkmod/data/BlockArea.java mode change 100644 => 100755 src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorMixin.java mode change 100644 => 100755 src/main/java/land/chipmunk/chipmunkmod/mixin/ChatScreenMixin.java mode change 100644 => 100755 src/main/java/land/chipmunk/chipmunkmod/mixin/ClientConnectionMixin.java mode change 100644 => 100755 src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerAccessor.java mode change 100644 => 100755 src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java mode change 100644 => 100755 src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayerEntityMixin.java mode change 100644 => 100755 src/main/java/land/chipmunk/chipmunkmod/mixin/MinecraftClientAccessor.java mode change 100644 => 100755 src/main/java/land/chipmunk/chipmunkmod/modules/CommandCore.java mode change 100644 => 100755 src/main/java/land/chipmunk/chipmunkmod/modules/SelfCare.java create mode 100644 src/main/resources/default_config.json diff --git a/src/main/java/land/chipmunk/chipmunkmod/ChipmunkMod.java b/src/main/java/land/chipmunk/chipmunkmod/ChipmunkMod.java old mode 100644 new mode 100755 index 4f165da..357c2ca --- a/src/main/java/land/chipmunk/chipmunkmod/ChipmunkMod.java +++ b/src/main/java/land/chipmunk/chipmunkmod/ChipmunkMod.java @@ -1,21 +1,64 @@ -package land.chipmunk.chipmunkmod; - -import net.fabricmc.api.ModInitializer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class ChipmunkMod implements ModInitializer { - // This logger is used to write text to the console and the log file. - // It is considered best practice to use your mod id as the logger's name. - // That way, it's clear which mod wrote info, warnings, and errors. - public static final Logger LOGGER = LoggerFactory.getLogger("chipmunkmod"); - - @Override - public void onInitialize () { - // This code runs as soon as Minecraft is in a mod-load-ready state. - // However, some things (like resources) may still be uninitialized. - // Proceed with mild caution. - - LOGGER.info("Hello Fabric world!"); - } -} +package land.chipmunk.chipmunkmod; + +import net.fabricmc.api.ModInitializer; +import java.io.InputStream; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.google.gson.Gson; + +public class ChipmunkMod implements ModInitializer { + // This logger is used to write text to the console and the log file. + // It is considered best practice to use your mod id as the logger's name. + // That way, it's clear which mod wrote info, warnings, and errors. + public static final Logger LOGGER = LoggerFactory.getLogger("chipmunkmod"); + public static Configuration CONFIG; + + @Override + public void onInitialize () { + // This code runs as soon as Minecraft is in a mod-load-ready state. + // However, some things (like resources) may still be uninitialized. + // Proceed with mild caution. + + try { + new File("config").mkdirs(); // TODO: Clean this up + CONFIG = loadConfig(); + } catch (IOException exception) { + throw new RuntimeException("Could not load the config", exception); + } + + LOGGER.info("Hello Fabric world!"); + } + + public static Configuration loadConfig () throws IOException { + final Gson gson = new Gson(); + final File file = new File("config/chipmunkmod.json"); + + if (!file.exists()) { + InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("default_config.json"); + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + + final StringBuilder sb = new StringBuilder(); + while (reader.ready()) sb.append((char) reader.read()); + final String defaultConfig = sb.toString(); + + // Write the default config + BufferedWriter configWriter = new BufferedWriter(new FileWriter(file)); + configWriter.write(defaultConfig); + configWriter.close(); + + return gson.fromJson(defaultConfig, Configuration.class); + } + + InputStream is = new FileInputStream(file); + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + + return gson.fromJson(reader, Configuration.class); + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/Configuration.java b/src/main/java/land/chipmunk/chipmunkmod/Configuration.java new file mode 100755 index 0000000..5ab2a1f --- /dev/null +++ b/src/main/java/land/chipmunk/chipmunkmod/Configuration.java @@ -0,0 +1,17 @@ +package land.chipmunk.chipmunkmod; + +import land.chipmunk.chipmunkmod.data.BlockArea; +import net.minecraft.util.math.BlockPos; + +public class Configuration { + public CommandManager commands = new CommandManager(); + public CommandCore core = new CommandCore(); + + public class CommandManager { + public String prefix = "."; + } + + public class CommandCore { + public BlockArea relativeArea = new BlockArea(new BlockPos(0, 0, 0), new BlockPos(15, 0, 15)); + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/command/CommandManager.java b/src/main/java/land/chipmunk/chipmunkmod/command/CommandManager.java old mode 100644 new mode 100755 index 117b608..fd0bbc1 --- a/src/main/java/land/chipmunk/chipmunkmod/command/CommandManager.java +++ b/src/main/java/land/chipmunk/chipmunkmod/command/CommandManager.java @@ -1,73 +1,74 @@ -package land.chipmunk.chipmunkmod.command; - -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.arguments.ArgumentType; -import com.mojang.brigadier.builder.LiteralArgumentBuilder; -import com.mojang.brigadier.builder.RequiredArgumentBuilder; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import net.minecraft.command.CommandException; -import net.minecraft.text.ClickEvent; -import net.minecraft.text.Text; -import net.minecraft.text.Texts; -import net.minecraft.text.MutableText; -import net.minecraft.util.Formatting; -import net.minecraft.client.MinecraftClient; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import land.chipmunk.chipmunkmod.commands.*; - -public class CommandManager { - public static CommandDispatcher dispatcher = new CommandDispatcher(); - public static String prefix = "."; - - public static void executeCommand (String command) { - final MinecraftClient client = MinecraftClient.getInstance(); - - final FabricClientCommandSource commandSource = (FabricClientCommandSource) client.getNetworkHandler().getCommandSource(); - - try { - dispatcher.execute(command, commandSource); - } catch (CommandSyntaxException e) { - commandSource.sendError(Texts.toText(e.getRawMessage())); - final Text context = getContext(e); - if (context != null) commandSource.sendError(context); - } catch (CommandException e) { - commandSource.sendError(e.getTextMessage()); - } catch (RuntimeException e) { - commandSource.sendError(Text.of(e.getMessage())); - } - } - - public static Text getContext (CommandSyntaxException exception) { - final int _cursor = exception.getCursor(); - final String input = exception.getInput(); - - if (input == null || _cursor < 0) { - return null; - } - final MutableText text = Text.literal("") - .formatted(Formatting.GRAY); - text.setStyle(text.getStyle().withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, prefix + input))); - - final int cursor = Math.min(input.length(), _cursor); - - if (cursor > CommandSyntaxException.CONTEXT_AMOUNT) { - text.append(Text.literal("...")); - } - - text - .append(Text.literal(input.substring(Math.max(0, cursor - CommandSyntaxException.CONTEXT_AMOUNT), cursor))) - .append(Text.literal(input.substring(cursor)).formatted(Formatting.RED, Formatting.UNDERLINE)) - .append(Text.translatable("command.context.here").formatted(Formatting.RED, Formatting.ITALIC)); - - return text; - } - - public static LiteralArgumentBuilder literal (String name) { return LiteralArgumentBuilder.literal(name); } - public static RequiredArgumentBuilder argument (String name, ArgumentType type) { return RequiredArgumentBuilder.argument(name, type); } - - static { - TestCommand.register(dispatcher); - CoreCommand.register(dispatcher); - UsernameCommand.register(dispatcher); - } +package land.chipmunk.chipmunkmod.command; + +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.ArgumentType; +import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import com.mojang.brigadier.builder.RequiredArgumentBuilder; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.minecraft.command.CommandException; +import net.minecraft.text.ClickEvent; +import net.minecraft.text.Text; +import net.minecraft.text.Texts; +import net.minecraft.text.MutableText; +import net.minecraft.util.Formatting; +import net.minecraft.client.MinecraftClient; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import land.chipmunk.chipmunkmod.ChipmunkMod; +import land.chipmunk.chipmunkmod.commands.*; + +public class CommandManager { + public static CommandDispatcher dispatcher = new CommandDispatcher(); + public static String prefix = ChipmunkMod.CONFIG.commands.prefix; + + public static void executeCommand (String command) { + final MinecraftClient client = MinecraftClient.getInstance(); + + final FabricClientCommandSource commandSource = (FabricClientCommandSource) client.getNetworkHandler().getCommandSource(); + + try { + dispatcher.execute(command, commandSource); + } catch (CommandSyntaxException e) { + commandSource.sendError(Texts.toText(e.getRawMessage())); + final Text context = getContext(e); + if (context != null) commandSource.sendError(context); + } catch (CommandException e) { + commandSource.sendError(e.getTextMessage()); + } catch (RuntimeException e) { + commandSource.sendError(Text.of(e.getMessage())); + } + } + + public static Text getContext (CommandSyntaxException exception) { + final int _cursor = exception.getCursor(); + final String input = exception.getInput(); + + if (input == null || _cursor < 0) { + return null; + } + final MutableText text = Text.literal("") + .formatted(Formatting.GRAY); + text.setStyle(text.getStyle().withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, prefix + input))); + + final int cursor = Math.min(input.length(), _cursor); + + if (cursor > CommandSyntaxException.CONTEXT_AMOUNT) { + text.append(Text.literal("...")); + } + + text + .append(Text.literal(input.substring(Math.max(0, cursor - CommandSyntaxException.CONTEXT_AMOUNT), cursor))) + .append(Text.literal(input.substring(cursor)).formatted(Formatting.RED, Formatting.UNDERLINE)) + .append(Text.translatable("command.context.here").formatted(Formatting.RED, Formatting.ITALIC)); + + return text; + } + + public static LiteralArgumentBuilder literal (String name) { return LiteralArgumentBuilder.literal(name); } + public static RequiredArgumentBuilder argument (String name, ArgumentType type) { return RequiredArgumentBuilder.argument(name, type); } + + static { + TestCommand.register(dispatcher); + CoreCommand.register(dispatcher); + UsernameCommand.register(dispatcher); + } } \ No newline at end of file diff --git a/src/main/java/land/chipmunk/chipmunkmod/commands/CoreCommand.java b/src/main/java/land/chipmunk/chipmunkmod/commands/CoreCommand.java old mode 100644 new mode 100755 index c8e6984..d901d8a --- a/src/main/java/land/chipmunk/chipmunkmod/commands/CoreCommand.java +++ b/src/main/java/land/chipmunk/chipmunkmod/commands/CoreCommand.java @@ -1,79 +1,79 @@ -package land.chipmunk.chipmunkmod.commands; - -import com.mojang.brigadier.Command; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.context.CommandContext; -import static land.chipmunk.chipmunkmod.command.CommandManager.literal; -import static land.chipmunk.chipmunkmod.command.CommandManager.argument; -import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; -import static com.mojang.brigadier.arguments.StringArgumentType.getString; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import net.minecraft.text.Text; -import net.minecraft.nbt.NbtCompound; -import java.util.concurrent.CompletableFuture; -import land.chipmunk.chipmunkmod.modules.CommandCore; - -public class CoreCommand { - public static void register (CommandDispatcher dispatcher) { - dispatcher.register( - literal("core") - .then( - literal("run") - .then( - argument("command", greedyString()) - .executes(c -> run(c)) - ) - ) - - .then( - literal("runTracked") - .then( - argument("command", greedyString()) - .executes(c -> runTracked(c)) - ) - ) - - .then(literal("refill").executes(c -> refill(c))) - .then(literal("move").executes(c -> move(c))) - ); - } - - public static int run (CommandContext context) { - CommandCore.INSTANCE.run(getString(context, "command")); - - return Command.SINGLE_SUCCESS; - } - - public static int runTracked (CommandContext context) { - final FabricClientCommandSource source = context.getSource(); - - final String command = getString(context, "command"); - - final CompletableFuture future = CommandCore.INSTANCE.runTracked(command); - future.thenApply(tag -> { - try { - final String output = tag.getString("LastOutput"); - if (output != null) source.sendFeedback(Text.Serializer.fromJson(output)); - } catch (Exception ignored) { - } - - return tag; - }); - - return Command.SINGLE_SUCCESS; - } - - public static int refill (CommandContext context) { - CommandCore.INSTANCE.refill(); - - return Command.SINGLE_SUCCESS; - } - - public static int move (CommandContext context) { - final FabricClientCommandSource source = context.getSource(); - - CommandCore.INSTANCE.move(source.getClient().player.getPos()); - - return Command.SINGLE_SUCCESS; - } -} +package land.chipmunk.chipmunkmod.commands; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.context.CommandContext; +import static land.chipmunk.chipmunkmod.command.CommandManager.literal; +import static land.chipmunk.chipmunkmod.command.CommandManager.argument; +import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; +import static com.mojang.brigadier.arguments.StringArgumentType.getString; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.text.Text; +import net.minecraft.nbt.NbtCompound; +import java.util.concurrent.CompletableFuture; +import land.chipmunk.chipmunkmod.modules.CommandCore; + +public class CoreCommand { + public static void register (CommandDispatcher dispatcher) { + dispatcher.register( + literal("core") + .then( + literal("run") + .then( + argument("command", greedyString()) + .executes(c -> run(c)) + ) + ) + + .then( + literal("runTracked") + .then( + argument("command", greedyString()) + .executes(c -> runTracked(c)) + ) + ) + + .then(literal("refill").executes(c -> refill(c))) + .then(literal("move").executes(c -> move(c))) + ); + } + + public static int run (CommandContext context) { + CommandCore.INSTANCE.run(getString(context, "command")); + + return Command.SINGLE_SUCCESS; + } + + public static int runTracked (CommandContext context) { + final FabricClientCommandSource source = context.getSource(); + + final String command = getString(context, "command"); + + final CompletableFuture future = CommandCore.INSTANCE.runTracked(command); + future.thenApply(tag -> { + try { + final String output = tag.getString("LastOutput"); + if (output != null) source.sendFeedback(Text.Serializer.fromJson(output)); + } catch (Exception ignored) { + } + + return tag; + }); + + return Command.SINGLE_SUCCESS; + } + + public static int refill (CommandContext context) { + CommandCore.INSTANCE.refill(); + + return Command.SINGLE_SUCCESS; + } + + public static int move (CommandContext context) { + final FabricClientCommandSource source = context.getSource(); + + CommandCore.INSTANCE.move(source.getClient().player.getPos()); + + return Command.SINGLE_SUCCESS; + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/commands/TestCommand.java b/src/main/java/land/chipmunk/chipmunkmod/commands/TestCommand.java old mode 100644 new mode 100755 index 716b558..9fb9a00 --- a/src/main/java/land/chipmunk/chipmunkmod/commands/TestCommand.java +++ b/src/main/java/land/chipmunk/chipmunkmod/commands/TestCommand.java @@ -1,24 +1,24 @@ -package land.chipmunk.chipmunkmod.commands; - -import com.mojang.brigadier.Command; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.context.CommandContext; -import static land.chipmunk.chipmunkmod.command.CommandManager.literal; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import net.minecraft.text.Text; - -public class TestCommand { - public static void register (CommandDispatcher dispatcher) { - dispatcher.register( - literal("test") - .executes(c -> helloWorld(c)) - ); - } - - public static int helloWorld (CommandContext context) { - final FabricClientCommandSource source = context.getSource(); - source.sendFeedback(Text.literal("Hello, world!")); - - return Command.SINGLE_SUCCESS; - } -} +package land.chipmunk.chipmunkmod.commands; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.context.CommandContext; +import static land.chipmunk.chipmunkmod.command.CommandManager.literal; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.text.Text; + +public class TestCommand { + public static void register (CommandDispatcher dispatcher) { + dispatcher.register( + literal("test") + .executes(c -> helloWorld(c)) + ); + } + + public static int helloWorld (CommandContext context) { + final FabricClientCommandSource source = context.getSource(); + source.sendFeedback(Text.literal("Hello, world!")); + + return Command.SINGLE_SUCCESS; + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/commands/UsernameCommand.java b/src/main/java/land/chipmunk/chipmunkmod/commands/UsernameCommand.java old mode 100644 new mode 100755 index d9595cd..c345afa --- a/src/main/java/land/chipmunk/chipmunkmod/commands/UsernameCommand.java +++ b/src/main/java/land/chipmunk/chipmunkmod/commands/UsernameCommand.java @@ -1,67 +1,67 @@ -package land.chipmunk.chipmunkmod.commands; - -import com.mojang.brigadier.Command; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.context.CommandContext; -import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; -import static com.mojang.brigadier.arguments.StringArgumentType.getString; -import static land.chipmunk.chipmunkmod.command.CommandManager.literal; -import static land.chipmunk.chipmunkmod.command.CommandManager.argument; -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.text.Text; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; -import java.util.Optional; -import land.chipmunk.chipmunkmod.mixin.MinecraftClientAccessor; - -public class UsernameCommand { - private static final Session ORIGINAL_SESSION = ((MinecraftClientAccessor) MinecraftClient.getInstance()).session(); - private static final SimpleCommandExceptionType USERNAME_TOO_LONG = new SimpleCommandExceptionType(Text.translatable("The specified username is longer than 16 characters")); - - public static void register (CommandDispatcher dispatcher) { - dispatcher.register( - literal("username") - .then( - literal("set") - .then( - argument("username", greedyString()) - .executes(c -> updateUsername(c)) - ) - ) - .then( - literal("revert") - .executes(c -> updateSession(c, ORIGINAL_SESSION)) - ) - ); - } - - public static int updateUsername (CommandContext context) throws CommandSyntaxException { - final String username = getString(context, "username"); - if (username.length() > 16) throw USERNAME_TOO_LONG.create(); - final Session session = new Session(username, "", "", Optional.empty(), Optional.empty(), Session.AccountType.MOJANG); - return updateSession(context, session); - } - - public static int updateSession (CommandContext context, Session session) throws CommandSyntaxException { - final FabricClientCommandSource source = context.getSource(); - - final MinecraftClient client = source.getClient(); - - ((MinecraftClientAccessor) client).session(session); - - // TODO: Put this in a separate class - final ServerInfo info = client.getCurrentServerEntry(); - client.world.disconnect(); - client.disconnect(); - ConnectScreen.connect(new MultiplayerScreen(new TitleScreen()), client, ServerAddress.parse(info.address), info); - - return Command.SINGLE_SUCCESS; - } -} +package land.chipmunk.chipmunkmod.commands; + +import com.mojang.brigadier.Command; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.context.CommandContext; +import static com.mojang.brigadier.arguments.StringArgumentType.greedyString; +import static com.mojang.brigadier.arguments.StringArgumentType.getString; +import static land.chipmunk.chipmunkmod.command.CommandManager.literal; +import static land.chipmunk.chipmunkmod.command.CommandManager.argument; +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.text.Text; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; +import java.util.Optional; +import land.chipmunk.chipmunkmod.mixin.MinecraftClientAccessor; + +public class UsernameCommand { + private static final Session ORIGINAL_SESSION = ((MinecraftClientAccessor) MinecraftClient.getInstance()).session(); + private static final SimpleCommandExceptionType USERNAME_TOO_LONG = new SimpleCommandExceptionType(Text.translatable("The specified username is longer than 16 characters")); + + public static void register (CommandDispatcher dispatcher) { + dispatcher.register( + literal("username") + .then( + literal("set") + .then( + argument("username", greedyString()) + .executes(c -> updateUsername(c)) + ) + ) + .then( + literal("revert") + .executes(c -> updateSession(c, ORIGINAL_SESSION)) + ) + ); + } + + public static int updateUsername (CommandContext context) throws CommandSyntaxException { + final String username = getString(context, "username"); + if (username.length() > 16) throw USERNAME_TOO_LONG.create(); + final Session session = new Session(username, "", "", Optional.empty(), Optional.empty(), Session.AccountType.MOJANG); + return updateSession(context, session); + } + + public static int updateSession (CommandContext context, Session session) throws CommandSyntaxException { + final FabricClientCommandSource source = context.getSource(); + + final MinecraftClient client = source.getClient(); + + ((MinecraftClientAccessor) client).session(session); + + // TODO: Put this in a separate class + final ServerInfo info = client.getCurrentServerEntry(); + client.world.disconnect(); + client.disconnect(); + ConnectScreen.connect(new MultiplayerScreen(new TitleScreen()), client, ServerAddress.parse(info.address), info); + + return Command.SINGLE_SUCCESS; + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/data/BlockArea.java b/src/main/java/land/chipmunk/chipmunkmod/data/BlockArea.java old mode 100644 new mode 100755 index 631d6c8..29093d3 --- a/src/main/java/land/chipmunk/chipmunkmod/data/BlockArea.java +++ b/src/main/java/land/chipmunk/chipmunkmod/data/BlockArea.java @@ -1,13 +1,13 @@ -package land.chipmunk.chipmunkmod.data; - -import net.minecraft.util.math.BlockPos; -import lombok.AllArgsConstructor; -import lombok.Data; - -// ? Am I reinventing the wheel here? -@AllArgsConstructor -@Data -public class BlockArea { - private BlockPos start; - private BlockPos end; -} +package land.chipmunk.chipmunkmod.data; + +import net.minecraft.util.math.BlockPos; +import lombok.AllArgsConstructor; +import lombok.Data; + +// ? Am I reinventing the wheel here? +@AllArgsConstructor +@Data +public class BlockArea { + private BlockPos start; + private BlockPos end; +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorMixin.java old mode 100644 new mode 100755 index 3d66baf..36393e6 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatInputSuggestorMixin.java @@ -1,50 +1,50 @@ -package land.chipmunk.chipmunkmod.mixin; - -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; -import java.util.concurrent.CompletableFuture; -import com.mojang.brigadier.suggestion.Suggestions; -import net.minecraft.client.gui.widget.TextFieldWidget; -import com.mojang.brigadier.CommandDispatcher; -import com.mojang.brigadier.StringReader; -import com.mojang.brigadier.exceptions.CommandSyntaxException; -import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; -import net.minecraft.client.MinecraftClient; -import land.chipmunk.chipmunkmod.command.CommandManager; - -@Mixin(net.minecraft.client.gui.screen.ChatInputSuggestor.class) -public class ChatInputSuggestorMixin { - @Shadow - CompletableFuture pendingSuggestions; - - @Shadow - public void show (boolean narrateFirstSuggestion) {} - - @Shadow - final TextFieldWidget textField; - - public ChatInputSuggestorMixin () { - textField = null; - } - - @Inject(at = @At("TAIL"), method = "refresh()V") - public void onRefresh (CallbackInfo ci) { - final String text = this.textField.getText(); - final int cursor = this.textField.getCursor(); - - 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); - } -} +package land.chipmunk.chipmunkmod.mixin; + +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; +import java.util.concurrent.CompletableFuture; +import com.mojang.brigadier.suggestion.Suggestions; +import net.minecraft.client.gui.widget.TextFieldWidget; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.StringReader; +import com.mojang.brigadier.exceptions.CommandSyntaxException; +import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource; +import net.minecraft.client.MinecraftClient; +import land.chipmunk.chipmunkmod.command.CommandManager; + +@Mixin(net.minecraft.client.gui.screen.ChatInputSuggestor.class) +public class ChatInputSuggestorMixin { + @Shadow + CompletableFuture pendingSuggestions; + + @Shadow + public void show (boolean narrateFirstSuggestion) {} + + @Shadow + final TextFieldWidget textField; + + public ChatInputSuggestorMixin () { + textField = null; + } + + @Inject(at = @At("TAIL"), method = "refresh()V") + public void onRefresh (CallbackInfo ci) { + final String text = this.textField.getText(); + final int cursor = this.textField.getCursor(); + + 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 old mode 100644 new mode 100755 index c197811..969fdb0 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatScreenMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ChatScreenMixin.java @@ -1,22 +1,22 @@ -package land.chipmunk.chipmunkmod.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import net.minecraft.client.MinecraftClient; -import land.chipmunk.chipmunkmod.command.CommandManager; - -@Mixin(net.minecraft.client.gui.screen.ChatScreen.class) -public class ChatScreenMixin { - @Inject(at = @At("HEAD"), method = "sendMessage", cancellable = true) - public void sendMessage(String chatText, boolean addToHistory, CallbackInfoReturnable cir) { - if (chatText.startsWith(CommandManager.prefix)) { - CommandManager.executeCommand(chatText.substring(CommandManager.prefix.length())); - - if (addToHistory) MinecraftClient.getInstance().inGameHud.getChatHud().addToMessageHistory(chatText); - - cir.setReturnValue(true); - } - } -} +package land.chipmunk.chipmunkmod.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import net.minecraft.client.MinecraftClient; +import land.chipmunk.chipmunkmod.command.CommandManager; + +@Mixin(net.minecraft.client.gui.screen.ChatScreen.class) +public class ChatScreenMixin { + @Inject(at = @At("HEAD"), method = "sendMessage", cancellable = true) + public void sendMessage(String chatText, boolean addToHistory, CallbackInfoReturnable cir) { + if (chatText.startsWith(CommandManager.prefix)) { + CommandManager.executeCommand(chatText.substring(CommandManager.prefix.length())); + + if (addToHistory) MinecraftClient.getInstance().inGameHud.getChatHud().addToMessageHistory(chatText); + + cir.setReturnValue(true); + } + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientConnectionMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientConnectionMixin.java old mode 100644 new mode 100755 index e2bee5b..a7025cd --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientConnectionMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientConnectionMixin.java @@ -1,20 +1,20 @@ -package land.chipmunk.chipmunkmod.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.text.Text; -import land.chipmunk.chipmunkmod.modules.CommandCore; -import land.chipmunk.chipmunkmod.modules.SelfCare; - -@Mixin(net.minecraft.network.ClientConnection.class) -public class ClientConnectionMixin { - @Inject(at = @At("HEAD"), method = "disconnect", cancellable = true) - public void disconnect (Text disconnectReason, CallbackInfo ci) { - if (disconnectReason == ClientPlayNetworkHandlerAccessor.chatValidationFailedText()) { - ci.cancel(); - } - } -} +package land.chipmunk.chipmunkmod.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.text.Text; +import land.chipmunk.chipmunkmod.modules.CommandCore; +import land.chipmunk.chipmunkmod.modules.SelfCare; + +@Mixin(net.minecraft.network.ClientConnection.class) +public class ClientConnectionMixin { + @Inject(at = @At("HEAD"), method = "disconnect", cancellable = true) + public void disconnect (Text disconnectReason, CallbackInfo ci) { + if (disconnectReason == ClientPlayNetworkHandlerAccessor.chatValidationFailedText()) { + ci.cancel(); + } + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerAccessor.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerAccessor.java old mode 100644 new mode 100755 index 22576d9..8170227 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerAccessor.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerAccessor.java @@ -1,11 +1,11 @@ -package land.chipmunk.chipmunkmod.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Accessor; -import net.minecraft.text.Text; - -@Mixin(net.minecraft.client.network.ClientPlayNetworkHandler.class) -public interface ClientPlayNetworkHandlerAccessor { - @Accessor("CHAT_VALIDATION_FAILED_TEXT") - public static Text chatValidationFailedText () { throw new AssertionError(); } -} +package land.chipmunk.chipmunkmod.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; +import net.minecraft.text.Text; + +@Mixin(net.minecraft.client.network.ClientPlayNetworkHandler.class) +public interface ClientPlayNetworkHandlerAccessor { + @Accessor("CHAT_VALIDATION_FAILED_TEXT") + public static Text chatValidationFailedText () { throw new AssertionError(); } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java old mode 100644 new mode 100755 index c422825..e968e5e --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayNetworkHandlerMixin.java @@ -1,16 +1,16 @@ -package land.chipmunk.chipmunkmod.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket; -import land.chipmunk.chipmunkmod.modules.SelfCare; - -@Mixin(net.minecraft.client.network.ClientPlayNetworkHandler.class) -public class ClientPlayNetworkHandlerMixin { - @Inject(method = "onGameJoin", at = @At("TAIL")) - private void onGameJoin (GameJoinS2CPacket packet, CallbackInfo ci) { - SelfCare.INSTANCE.init(); - } -} +package land.chipmunk.chipmunkmod.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket; +import land.chipmunk.chipmunkmod.modules.SelfCare; + +@Mixin(net.minecraft.client.network.ClientPlayNetworkHandler.class) +public class ClientPlayNetworkHandlerMixin { + @Inject(method = "onGameJoin", at = @At("TAIL")) + private void onGameJoin (GameJoinS2CPacket packet, CallbackInfo ci) { + SelfCare.INSTANCE.init(); + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayerEntityMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayerEntityMixin.java old mode 100644 new mode 100755 index 429b714..abdb4b3 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayerEntityMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/ClientPlayerEntityMixin.java @@ -1,34 +1,34 @@ -package land.chipmunk.chipmunkmod.mixin; - -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; -import net.minecraft.client.network.ClientPlayerEntity; -import net.minecraft.entity.MovementType; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.util.math.Vec3d; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec2f; -import land.chipmunk.chipmunkmod.modules.CommandCore; - -@Mixin(ClientPlayerEntity.class) -public class ClientPlayerEntityMixin { - private static MinecraftClient CLIENT = MinecraftClient.getInstance(); - - @Inject(at = @At("HEAD"), method = "move") - public void move (MovementType type, Vec3d relPos, CallbackInfo ci) { - if ((ClientPlayerEntity) (Object) this != CLIENT.player) return; - - final Vec3d position = ((ClientPlayerEntity) (Object) this).getPos().add(relPos); - - final ClientWorld world = CLIENT.getNetworkHandler().getWorld(); - - 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); - } -} +package land.chipmunk.chipmunkmod.mixin; + +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; +import net.minecraft.client.network.ClientPlayerEntity; +import net.minecraft.entity.MovementType; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.util.math.Vec3d; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec2f; +import land.chipmunk.chipmunkmod.modules.CommandCore; + +@Mixin(ClientPlayerEntity.class) +public class ClientPlayerEntityMixin { + private static MinecraftClient CLIENT = MinecraftClient.getInstance(); + + @Inject(at = @At("HEAD"), method = "move") + public void move (MovementType type, Vec3d relPos, CallbackInfo ci) { + if ((ClientPlayerEntity) (Object) this != CLIENT.player) return; + + final Vec3d position = ((ClientPlayerEntity) (Object) this).getPos().add(relPos); + + final ClientWorld world = CLIENT.getNetworkHandler().getWorld(); + + 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); + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/MinecraftClientAccessor.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/MinecraftClientAccessor.java old mode 100644 new mode 100755 index 9ea5de9..4a45e34 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/MinecraftClientAccessor.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/MinecraftClientAccessor.java @@ -1,16 +1,16 @@ -package land.chipmunk.chipmunkmod.mixin; - -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 { - @Accessor("session") - Session session (); - - @Mutable - @Accessor("session") - void session (Session session); -} +package land.chipmunk.chipmunkmod.mixin; + +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 { + @Accessor("session") + Session session (); + + @Mutable + @Accessor("session") + void session (Session session); +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/modules/CommandCore.java b/src/main/java/land/chipmunk/chipmunkmod/modules/CommandCore.java old mode 100644 new mode 100755 index 09c9af5..c23a0f5 --- a/src/main/java/land/chipmunk/chipmunkmod/modules/CommandCore.java +++ b/src/main/java/land/chipmunk/chipmunkmod/modules/CommandCore.java @@ -1,147 +1,148 @@ -package land.chipmunk.chipmunkmod.modules; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.network.ClientConnection; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; -import net.minecraft.network.packet.c2s.play.UpdateCommandBlockC2SPacket; -import net.minecraft.block.entity.CommandBlockBlockEntity; -import net.minecraft.nbt.NbtCompound; -import lombok.Getter; -import lombok.Setter; -import java.util.List; -import java.util.ArrayList; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.CompletableFuture; -import java.util.function.Consumer; -import land.chipmunk.chipmunkmod.data.BlockArea; - -public class CommandCore { - private MinecraftClient client; - @Getter @Setter private boolean ready = false; - @Getter @Setter private BlockPos origin; - // TODO: Make it configurable - @Getter private final BlockArea relativeArea = new BlockArea(new BlockPos(0, 0, 0), new BlockPos(15, 0, 15)); - @Getter @Setter private BlockPos currentBlockRelative; - - public static CommandCore INSTANCE = new CommandCore(MinecraftClient.getInstance()); - - public CommandCore (MinecraftClient client) { - this.client = client; - } - - public void move (Vec3d position) { - if (!ready) { - ready = true; - // for (Listener listener : listeners) listener.ready(); - } - - origin = new BlockPos( - ((int) position.getX() / 16) * 16, - 0, // TODO: Use the actual bottom of the world instead of hardcoding to 0 - ((int) position.getZ() / 16) * 16 - ); - - if (currentBlockRelative == null) currentBlockRelative = new BlockPos(relativeArea.start()); - refill(); - } - - public void refill () { - // final PositionManager position = client.position(); - final BlockPos relStart = relativeArea.start(); - final BlockPos relEnd = relativeArea.end(); - - final String command = String.format( - "fill %s %s %s %s %s %s command_block", - relStart.getX() + origin.getX(), - relStart.getY() + origin.getY(), - relStart.getZ() + origin.getZ(), - - relEnd.getX() + origin.getX(), - relEnd.getY() + origin.getY(), - relEnd.getZ() + origin.getZ() - ); - - client.getNetworkHandler().sendChatCommand(command); - } - - public void incrementCurrentBlock () { - final BlockPos start = relativeArea.start(); - final BlockPos end = relativeArea.end(); - - int x = currentBlockRelative.getX(); - int y = currentBlockRelative.getY(); - int z = currentBlockRelative.getZ(); - - x++; - - if (x > end.getX()) { - x = start.getX(); - z++; - } - - if (z > end.getZ()) { - z = start.getZ(); - y++; - } - - if (y > end.getY()) { - x = start.getX(); - y = start.getY(); - z = start.getZ(); - } - - currentBlockRelative = new BlockPos(x, y, z); - } - - public BlockPos currentBlockAbsolute () { - return currentBlockRelative.add(origin); - } - - public void run (String command) { - final ClientConnection connection = client.getNetworkHandler().getConnection(); - final BlockPos currentBlock = currentBlockAbsolute(); - - // TODO: Support using repeating command blocks (on kaboom-like servers) (because less packets) - connection.send(new UpdateCommandBlockC2SPacket(currentBlock, "", CommandBlockBlockEntity.Type.REDSTONE, false, false, false)); - connection.send(new UpdateCommandBlockC2SPacket(currentBlock, command, CommandBlockBlockEntity.Type.REDSTONE, false, false, true)); - - incrementCurrentBlock(); - } - - public CompletableFuture runTracked (String command) { - final ClientConnection connection = client.getNetworkHandler().getConnection(); - final BlockPos currentBlock = currentBlockAbsolute(); - - // TODO: Support using repeating command blocks (on kaboom-like servers) (because less packets) - connection.send(new UpdateCommandBlockC2SPacket(currentBlock, "", CommandBlockBlockEntity.Type.SEQUENCE, false, false, false)); - connection.send(new UpdateCommandBlockC2SPacket(currentBlock, command, CommandBlockBlockEntity.Type.REDSTONE, true, false, true)); - - incrementCurrentBlock(); - - CompletableFuture future = new CompletableFuture(); - - final Timer timer = new Timer(); - - final TimerTask queryTask = new TimerTask() { - public void run () { - client.getNetworkHandler().getDataQueryHandler().queryBlockNbt(currentBlock, - tag -> { future.complete(tag); }); - - timer.cancel(); // ? Is this necesary? - timer.purge(); - } - }; - - timer.schedule(queryTask, 50); - - return future; - } - - public void cleanup () { - origin = null; - currentBlockRelative = null; - ready = false; - } -} +package land.chipmunk.chipmunkmod.modules; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.network.ClientConnection; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.network.packet.c2s.play.UpdateCommandBlockC2SPacket; +import net.minecraft.block.entity.CommandBlockBlockEntity; +import net.minecraft.nbt.NbtCompound; +import lombok.Getter; +import lombok.Setter; +import java.util.List; +import java.util.ArrayList; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; +import land.chipmunk.chipmunkmod.ChipmunkMod; +import land.chipmunk.chipmunkmod.data.BlockArea; + +public class CommandCore { + private MinecraftClient client; + @Getter @Setter private boolean ready = false; + @Getter @Setter private BlockPos origin; + @Getter private final BlockArea relativeArea; + @Getter @Setter private BlockPos currentBlockRelative; + + public static CommandCore INSTANCE = new CommandCore(MinecraftClient.getInstance(), ChipmunkMod.CONFIG.core.relativeArea); + + public CommandCore (MinecraftClient client, BlockArea relativeArea) { + this.client = client; + this.relativeArea = relativeArea; + } + + public void move (Vec3d position) { + if (!ready) { + ready = true; + // for (Listener listener : listeners) listener.ready(); + } + + origin = new BlockPos( + ((int) position.getX() / 16) * 16, + 0, // TODO: Use the actual bottom of the world instead of hardcoding to 0 + ((int) position.getZ() / 16) * 16 + ); + + if (currentBlockRelative == null) currentBlockRelative = new BlockPos(relativeArea.start()); + refill(); + } + + public void refill () { + // final PositionManager position = client.position(); + final BlockPos relStart = relativeArea.start(); + final BlockPos relEnd = relativeArea.end(); + + final String command = String.format( + "fill %s %s %s %s %s %s command_block", + relStart.getX() + origin.getX(), + relStart.getY() + origin.getY(), + relStart.getZ() + origin.getZ(), + + relEnd.getX() + origin.getX(), + relEnd.getY() + origin.getY(), + relEnd.getZ() + origin.getZ() + ); + + client.getNetworkHandler().sendChatCommand(command); + } + + public void incrementCurrentBlock () { + final BlockPos start = relativeArea.start(); + final BlockPos end = relativeArea.end(); + + int x = currentBlockRelative.getX(); + int y = currentBlockRelative.getY(); + int z = currentBlockRelative.getZ(); + + x++; + + if (x > end.getX()) { + x = start.getX(); + z++; + } + + if (z > end.getZ()) { + z = start.getZ(); + y++; + } + + if (y > end.getY()) { + x = start.getX(); + y = start.getY(); + z = start.getZ(); + } + + currentBlockRelative = new BlockPos(x, y, z); + } + + public BlockPos currentBlockAbsolute () { + return currentBlockRelative.add(origin); + } + + public void run (String command) { + final ClientConnection connection = client.getNetworkHandler().getConnection(); + final BlockPos currentBlock = currentBlockAbsolute(); + + // TODO: Support using repeating command blocks (on kaboom-like servers) (because less packets) + connection.send(new UpdateCommandBlockC2SPacket(currentBlock, "", CommandBlockBlockEntity.Type.REDSTONE, false, false, false)); + connection.send(new UpdateCommandBlockC2SPacket(currentBlock, command, CommandBlockBlockEntity.Type.REDSTONE, false, false, true)); + + incrementCurrentBlock(); + } + + public CompletableFuture runTracked (String command) { + final ClientConnection connection = client.getNetworkHandler().getConnection(); + final BlockPos currentBlock = currentBlockAbsolute(); + + // TODO: Support using repeating command blocks (on kaboom-like servers) (because less packets) + connection.send(new UpdateCommandBlockC2SPacket(currentBlock, "", CommandBlockBlockEntity.Type.SEQUENCE, false, false, false)); + connection.send(new UpdateCommandBlockC2SPacket(currentBlock, command, CommandBlockBlockEntity.Type.REDSTONE, true, false, true)); + + incrementCurrentBlock(); + + CompletableFuture future = new CompletableFuture(); + + final Timer timer = new Timer(); + + final TimerTask queryTask = new TimerTask() { + public void run () { + client.getNetworkHandler().getDataQueryHandler().queryBlockNbt(currentBlock, + tag -> { future.complete(tag); }); + + timer.cancel(); // ? Is this necesary? + timer.purge(); + } + }; + + timer.schedule(queryTask, 50); + + return future; + } + + public void cleanup () { + origin = null; + currentBlockRelative = null; + ready = false; + } +} diff --git a/src/main/java/land/chipmunk/chipmunkmod/modules/SelfCare.java b/src/main/java/land/chipmunk/chipmunkmod/modules/SelfCare.java old mode 100644 new mode 100755 index 7319aaf..af72cd3 --- a/src/main/java/land/chipmunk/chipmunkmod/modules/SelfCare.java +++ b/src/main/java/land/chipmunk/chipmunkmod/modules/SelfCare.java @@ -1,72 +1,72 @@ -package land.chipmunk.chipmunkmod.modules; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.client.network.ClientPlayerEntity; -import com.mojang.brigadier.tree.CommandNode; -import com.mojang.brigadier.tree.LiteralCommandNode; -import lombok.Getter; -import java.util.Timer; -import java.util.TimerTask; - -public class SelfCare { - private final MinecraftClient client; - @Getter private long interval; - - private Timer timer = null; - - public static final SelfCare INSTANCE = new SelfCare(MinecraftClient.getInstance(), 70L); - - public SelfCare (MinecraftClient client, long interval) { - this.client = client; - this.interval = interval; - } - - public void init () { - final TimerTask task = new TimerTask() { - public void run () { - tick(); - } - }; - - if (timer != null) cleanup(); - - timer = new Timer(); - timer.schedule(task, interval, interval); - } - - public void cleanup () { - if (timer == null) return; - - timer.cancel(); - timer.purge(); - timer = null; - } - - public void tick () { - final ClientPlayerEntity player = client.player; - final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler(); - - if (networkHandler == null) { - cleanup(); - return; - } - - if (!player.hasPermissionLevel(2)) { if (serverHasCommand("op")) networkHandler.sendChatCommand("op @s[type=player]"); } - else if (!client.player.isCreative()) networkHandler.sendChatCommand("gamemode creative"); - } - - // TODO: Move this into a separate class related to server info gathering (and yes, I plan on making this d y n a m i c and require little to no configuration for most servers) - private boolean serverHasCommand (String name) { - final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler(); - - for (CommandNode node : networkHandler.getCommandDispatcher().getRoot().getChildren()) { - if (!(node instanceof LiteralCommandNode)) continue; - final LiteralCommandNode literal = (LiteralCommandNode) node; - - if (literal.getLiteral().equals(name)) return true; - } - - return false; - } -} +package land.chipmunk.chipmunkmod.modules; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.network.ClientPlayNetworkHandler; +import net.minecraft.client.network.ClientPlayerEntity; +import com.mojang.brigadier.tree.CommandNode; +import com.mojang.brigadier.tree.LiteralCommandNode; +import lombok.Getter; +import java.util.Timer; +import java.util.TimerTask; + +public class SelfCare { + private final MinecraftClient client; + @Getter private long interval; + + private Timer timer = null; + + public static final SelfCare INSTANCE = new SelfCare(MinecraftClient.getInstance(), 70L); + + public SelfCare (MinecraftClient client, long interval) { + this.client = client; + this.interval = interval; + } + + public void init () { + final TimerTask task = new TimerTask() { + public void run () { + tick(); + } + }; + + if (timer != null) cleanup(); + + timer = new Timer(); + timer.schedule(task, interval, interval); + } + + public void cleanup () { + if (timer == null) return; + + timer.cancel(); + timer.purge(); + timer = null; + } + + public void tick () { + final ClientPlayerEntity player = client.player; + final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler(); + + if (networkHandler == null) { + cleanup(); + return; + } + + if (!player.hasPermissionLevel(2)) { if (serverHasCommand("op")) networkHandler.sendChatCommand("op @s[type=player]"); } + else if (!client.player.isCreative()) networkHandler.sendChatCommand("gamemode creative"); + } + + // TODO: Move this into a separate class related to server info gathering (and yes, I plan on making this d y n a m i c and require little to no configuration for most servers) + private boolean serverHasCommand (String name) { + final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler(); + + for (CommandNode node : networkHandler.getCommandDispatcher().getRoot().getChildren()) { + if (!(node instanceof LiteralCommandNode)) continue; + final LiteralCommandNode literal = (LiteralCommandNode) node; + + if (literal.getLiteral().equals(name)) return true; + } + + return false; + } +} diff --git a/src/main/resources/default_config.json b/src/main/resources/default_config.json new file mode 100644 index 0000000..a9179b8 --- /dev/null +++ b/src/main/resources/default_config.json @@ -0,0 +1,12 @@ +{ + "commands": { + "prefix": "." + }, + + "core": { + "relativeArea": { + "start": { "x": 0, "y": 0, "z": 0 }, + "end": { "x": 15, "y": 0, "z": 15 } + } + } +} \ No newline at end of file