dfghjkl;'

This commit is contained in:
kawaiizenbo 2022-12-06 21:59:13 -07:00
parent baf8d849b6
commit 412cabff8a
23 changed files with 706 additions and 18 deletions

View file

@ -1,9 +1 @@
# Fabric Example Mod
## Setup
For setup instructions please see the [fabric wiki page](https://fabricmc.net/wiki/tutorial:setup) that relates to the IDE that you are using.
## License
This template is available under the CC0 license. Feel free to learn from it and incorporate it in your own projects.
Moonlight Meadows Utility Mod

View file

@ -0,0 +1,84 @@
package me.kawaiizenbo.moonlight.command;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import net.minecraft.client.MinecraftClient;
import net.minecraft.command.CommandSource;
public abstract class Command
{
protected static MinecraftClient mc;
private final String name;
private final String description;
private final List<String> aliases = new ArrayList<>();
public int SINGLE_SUCCESS = com.mojang.brigadier.Command.SINGLE_SUCCESS;
public Command(String name, String description, String... aliases) {
this.name = name;
this.description = description;
Collections.addAll(this.aliases, aliases);
mc = MinecraftClient.getInstance();
}
// Helper methods to painlessly infer the CommandSource generic type argument
protected static <T> RequiredArgumentBuilder<CommandSource, T> argument(final String name, final ArgumentType<T> type) {
return RequiredArgumentBuilder.argument(name, type);
}
protected static LiteralArgumentBuilder<CommandSource> literal(final String name) {
return LiteralArgumentBuilder.literal(name);
}
public final void registerTo(CommandDispatcher<CommandSource> dispatcher) {
register(dispatcher, name);
for (String alias : aliases) register(dispatcher, alias);
}
public void register(CommandDispatcher<CommandSource> dispatcher, String name) {
LiteralArgumentBuilder<CommandSource> builder = LiteralArgumentBuilder.literal(name);
build(builder);
dispatcher.register(builder);
}
public abstract void build(LiteralArgumentBuilder<CommandSource> builder);
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public List<String> getAliases() {
return aliases;
}
public String toString() {
return CommandManager.get().getPrefix() + name;
}
public String toString(String... args) {
StringBuilder base = new StringBuilder(toString());
for (String arg : args)
base.append(' ').append(arg);
return base.toString();
}
public static String nameToTitle(String name) {
return Arrays.stream(name.split("-")).map(StringUtils::capitalize).collect(Collectors.joining(" "));
}
}

View file

@ -0,0 +1,86 @@
package me.kawaiizenbo.moonlight.command;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.ParseResults;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientCommandSource;
import net.minecraft.command.CommandSource;
import me.kawaiizenbo.moonlight.command.commands.*;
public class CommandManager
{
private static MinecraftClient mc = MinecraftClient.getInstance();
private final CommandDispatcher<CommandSource> DISPATCHER = new CommandDispatcher<>();
private final CommandSource COMMAND_SOURCE = new ChatCommandSource(mc);
private final List<Command> commands = new ArrayList<>();
private final Map<Class<? extends Command>, Command> commandInstances = new HashMap<>();
private CommandManager() {
add(new VClip());
add(new Help());
add(new Toggle());
commands.sort(Comparator.comparing(Command::getName));
}
public static CommandManager get() {
return new CommandManager();
}
public void dispatch(String message) throws CommandSyntaxException {
dispatch(message, new ChatCommandSource(mc));
}
public void dispatch(String message, CommandSource source) throws CommandSyntaxException {
ParseResults<CommandSource> results = DISPATCHER.parse(message, source);
DISPATCHER.execute(results);
}
public CommandDispatcher<CommandSource> getDispatcher() {
return DISPATCHER;
}
public CommandSource getCommandSource() {
return COMMAND_SOURCE;
}
private final static class ChatCommandSource extends ClientCommandSource {
public ChatCommandSource(MinecraftClient client) {
super(null, client);
}
}
public void add(Command command) {
commands.removeIf(command1 -> command1.getName().equals(command.getName()));
commandInstances.values().removeIf(command1 -> command1.getName().equals(command.getName()));
command.registerTo(DISPATCHER);
commands.add(command);
commandInstances.put(command.getClass(), command);
}
public int getCount() {
return commands.size();
}
public List<Command> getAll() {
return commands;
}
@SuppressWarnings("unchecked")
public <T extends Command> T get(Class<T> klass) {
return (T) commandInstances.get(klass);
}
public String getPrefix() {
return "?";
}
}

View file

@ -0,0 +1,63 @@
package me.kawaiizenbo.moonlight.command;
import java.util.Collection;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import me.kawaiizenbo.moonlight.module.Module_;
import me.kawaiizenbo.moonlight.module.ModuleManager;
import net.minecraft.command.CommandSource;
import net.minecraft.text.Text;
public class ModuleArgumentType implements ArgumentType<Module_>
{
private static final Collection<String> EXAMPLES = ModuleManager.INSTANCE.modules
.stream()
.limit(3)
.map(module -> module.name)
.collect(Collectors.toList());
private static final DynamicCommandExceptionType NO_SUCH_MODULE = new DynamicCommandExceptionType(o ->
Text.literal("Module with name " + o + " doesn't exist."));
public static ModuleArgumentType module()
{
return new ModuleArgumentType();
}
public static Module_ getModule(final CommandContext<?> context, final String name)
{
return context.getArgument(name, Module_.class);
}
@Override
public Module_ parse(StringReader reader) throws CommandSyntaxException
{
String argument = reader.readString();
Module_ module = ModuleManager.INSTANCE.getModuleByName(argument);
if (module == null) throw NO_SUCH_MODULE.create(argument);
return module;
}
@Override
public <S> CompletableFuture<Suggestions> listSuggestions(CommandContext<S> context, SuggestionsBuilder builder)
{
return CommandSource.suggestMatching(ModuleManager.INSTANCE.modules.stream().map(module -> module.name), builder);
}
@Override
public Collection<String> getExamples()
{
return EXAMPLES;
}
}

View file

@ -0,0 +1,32 @@
package me.kawaiizenbo.moonlight.command.commands;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.kawaiizenbo.moonlight.command.Command;
import me.kawaiizenbo.moonlight.command.CommandManager;
import me.kawaiizenbo.moonlight.util.ChatUtils;
import me.kawaiizenbo.moonlight.util.ColorUtils;
import net.minecraft.command.CommandSource;
public class Help extends Command
{
public Help()
{
super("help", "Gives you a list of all of the commands");
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder)
{
builder.executes(context ->
{
for (Command cmd : CommandManager.get().getAll()) {
ChatUtils.sendMsg(ColorUtils.aqua + "Command: " + ColorUtils.gray + cmd.getName());
ChatUtils.sendMsg(ColorUtils.gray + cmd.getDescription());
}
return SINGLE_SUCCESS;
});
}
}

View file

@ -0,0 +1,34 @@
package me.kawaiizenbo.moonlight.command.commands;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.kawaiizenbo.moonlight.command.Command;
import me.kawaiizenbo.moonlight.command.ModuleArgumentType;
import me.kawaiizenbo.moonlight.module.Module_;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.command.CommandSource;
public class Toggle extends Command
{
public Toggle()
{
super("toggle", "Toggle a module.");
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder)
{
builder.then(argument("module", new ModuleArgumentType()).executes(context ->
{
ClientPlayerEntity player = mc.player;
assert player != null;
Module_ m = context.getArgument("module", Module_.class);
m.toggle();
return SINGLE_SUCCESS;
}));
}
}

View file

@ -0,0 +1,39 @@
package me.kawaiizenbo.moonlight.command.commands;
import com.mojang.brigadier.arguments.DoubleArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.kawaiizenbo.moonlight.command.Command;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.command.CommandSource;
import net.minecraft.entity.Entity;
public class VClip extends Command
{
public VClip()
{
super("vclip", "Teleports you vertically.");
}
@Override
public void build(LiteralArgumentBuilder<CommandSource> builder)
{
builder.then(argument("blocks", DoubleArgumentType.doubleArg()).executes(context ->
{
ClientPlayerEntity player = mc.player;
assert player != null;
double blocks = context.getArgument("blocks", Double.class);
if (player.hasVehicle())
{
Entity vehicle = player.getVehicle();
vehicle.setPosition(vehicle.getX(), vehicle.getY() + blocks, vehicle.getZ());
}
player.setPosition(player.getX(), player.getY() + blocks, player.getZ());
return SINGLE_SUCCESS;
}));
}
}

View file

@ -0,0 +1,72 @@
package me.kawaiizenbo.moonlight.mixin;
import java.util.concurrent.CompletableFuture;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.ParseResults;
import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.suggestion.Suggestions;
import me.kawaiizenbo.moonlight.command.CommandManager;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ChatInputSuggestor;
import net.minecraft.client.gui.screen.ChatInputSuggestor.SuggestionWindow;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.command.CommandSource;
@Mixin(ChatInputSuggestor.class)
public abstract class ChatInputSuggestorMixin
{
@Shadow private ParseResults<CommandSource> parse;
@Shadow @Final private TextFieldWidget textField;
@Shadow @Final private MinecraftClient client;
@Shadow private boolean completingSuggestions;
@Shadow private CompletableFuture<Suggestions> pendingSuggestions;
@Shadow private SuggestionWindow window;
@Shadow protected abstract void showCommandSuggestions();
@Inject(method = "refresh",
at = @At(value = "INVOKE", target = "Lcom/mojang/brigadier/StringReader;canRead()Z", remap = false),
cancellable = true,
locals = LocalCapture.CAPTURE_FAILHARD)
public void onRefresh(CallbackInfo ci, String string, StringReader reader) {
String prefix = CommandManager.get().getPrefix();
int length = prefix.length();
if (reader.canRead(length) && reader.getString().startsWith(prefix, reader.getCursor())) {
reader.setCursor(reader.getCursor() + length);
assert this.client.player != null;
// Pretty much copy&paste from the refresh method
CommandDispatcher<CommandSource> commandDispatcher = CommandManager.get().getDispatcher();
if (this.parse == null) {
this.parse = commandDispatcher.parse(reader, CommandManager.get().getCommandSource());
}
int cursor = textField.getCursor();
if (cursor >= 1 && (this.window == null || !this.completingSuggestions)) {
this.pendingSuggestions = commandDispatcher.getCompletionSuggestions(this.parse, cursor);
this.pendingSuggestions.thenRun(() -> {
if (this.pendingSuggestions.isDone()) {
showCommandSuggestions();
}
});
}
ci.cancel();
}
}
}

View file

@ -0,0 +1,37 @@
package me.kawaiizenbo.moonlight.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 com.mojang.brigadier.exceptions.CommandSyntaxException;
import me.kawaiizenbo.moonlight.command.CommandManager;
import me.kawaiizenbo.moonlight.util.ChatUtils;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.Packet;
import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket;
@Mixin(ClientConnection.class)
public class ClientConnectionMixin
{
@Inject(method = "send(Lnet/minecraft/network/Packet;)V", at = @At("HEAD"), cancellable = true)
public void send(Packet<?> packet, CallbackInfo ci)
{
// Call commands if the prefix is sent
if(packet instanceof ChatMessageC2SPacket && ((ChatMessageC2SPacket) packet).chatMessage().startsWith(CommandManager.get().getPrefix()))
{
try
{
CommandManager.get().dispatch(((ChatMessageC2SPacket) packet).chatMessage().substring(CommandManager.get().getPrefix().length()));
}
catch (CommandSyntaxException e)
{
e.printStackTrace();
ChatUtils.sendMsg(e.getMessage());
}
ci.cancel();
}
}
}

View file

@ -0,0 +1,25 @@
package me.kawaiizenbo.moonlight.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 me.kawaiizenbo.moonlight.ui.HUD;
import net.minecraft.client.gui.hud.InGameHud;
import net.minecraft.client.util.math.MatrixStack;
@Mixin(InGameHud.class)
public class InGameHudMixin {
@Shadow private int scaledWidth;
@Shadow private int scaledHeight;
@Inject(at = @At("TAIL"), method = "render")
public void onRender (MatrixStack matrices, float tickDelta, CallbackInfo info)
{
HUD.INSTANCE.renderHUD(matrices, scaledWidth, scaledHeight);
}
}

View file

@ -0,0 +1,25 @@
package me.kawaiizenbo.moonlight.mixin;
import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.LivingEntity;
import me.kawaiizenbo.moonlight.module.Module_;
import me.kawaiizenbo.moonlight.module.ModuleManager;
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;
@Mixin(LivingEntity.class)
public class LivingEntityMixin
{
@Inject(at = @At("HEAD"), method = "tick()V")
private void init(CallbackInfo info)
{
for (Module_ mod : ModuleManager.INSTANCE.getEnabledModules())
{
if (MinecraftClient.getInstance().player != null) mod.tick();
}
}
}

View file

@ -1,12 +1,11 @@
package me.kawaiizenbo.moonlight.mixin;
import me.kawaiizenbo.moonlight.ui.AltManagerScreen;
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 me.kawaiizenbo.moonlight.ui.altmanager.AltManagerScreen;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.multiplayer.MultiplayerScreen;

View file

@ -1,7 +1,7 @@
package me.kawaiizenbo.moonlight.mixin;
import me.kawaiizenbo.moonlight.Moonlight;
import me.kawaiizenbo.moonlight.ui.AltManagerScreen;
import me.kawaiizenbo.moonlight.ui.altmanager.AltManagerScreen;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;

View file

@ -0,0 +1,47 @@
package me.kawaiizenbo.moonlight.module;
import java.util.ArrayList;
import me.kawaiizenbo.moonlight.module.modules.*;
public class ModuleManager
{
public static ModuleManager INSTANCE = new ModuleManager();
public ArrayList<Module_> modules = new ArrayList<>();
public ModuleManager()
{
registerModules(new Fly());
}
public void registerModule(Module_ module) {
modules.add(module);
}
public void registerModules(Module_... modules) {
for (Module_ module : modules) {
this.modules.add(module);
}
}
public Module_ getModuleByName(String moduleName) {
for(Module_ mod : modules) {
if ((mod.name.trim().equalsIgnoreCase(moduleName)) || (mod.toString().trim().equalsIgnoreCase(moduleName.trim()))) {
return mod;
}
}
return null;
}
public ArrayList<Module_> getEnabledModules()
{
ArrayList<Module_> enabledModules = new ArrayList<>();
for (Module_ module : modules)
{
if (!module.enabled)
continue;
enabledModules.add(module);
}
return enabledModules;
}
}

View file

@ -0,0 +1,31 @@
package me.kawaiizenbo.moonlight.module;
import net.minecraft.client.MinecraftClient;
public abstract class Module_
{
protected static MinecraftClient mc = MinecraftClient.getInstance();
public String name;
public String description;
public boolean enabled;
public Module_(String name, String description)
{
this.name = name;
this.description = description;
}
public void onEnable() {}
public void onDisable() {}
public void tick() {}
public void toggle()
{
enabled = !enabled;
if(enabled) {
onEnable();
} else {
onDisable();
}
}
}

View file

@ -0,0 +1,24 @@
package me.kawaiizenbo.moonlight.module.modules;
import me.kawaiizenbo.moonlight.module.Module_;
public class Fly extends Module_
{
public Fly()
{
super("Fly", "Allows you to fly in survival mode.");
}
@Override
public void tick()
{
mc.player.getAbilities().flying = true;
}
@Override
public void onDisable()
{
mc.player.getAbilities().flying = false;
}
}

View file

@ -0,0 +1,57 @@
package me.kawaiizenbo.moonlight.ui;
import java.math.BigDecimal;
import java.math.RoundingMode;
import me.kawaiizenbo.moonlight.Moonlight;
import me.kawaiizenbo.moonlight.util.ColorUtils;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
public class HUD
{
public static HUD INSTANCE = new HUD();
private MinecraftClient mc = MinecraftClient.getInstance();
TextRenderer textRenderer = mc.textRenderer;
public void renderHUD(MatrixStack matrix, int scaledWidth, int scaledHeight)
{
// do not draw if F3 enabled
if (mc.options.debugEnabled) return;
// draw stats
textRenderer.drawWithShadow(matrix, Moonlight.clientTag + " " + Moonlight.versionTag, 2, 2, 16777215);
textRenderer.drawWithShadow(matrix, "FPS: " + ColorUtils.gray + mc.fpsDebugString.split(" ")[0], 2, 12, 0x55FFFF);
textRenderer.drawWithShadow(matrix, "Ping: " + ColorUtils.gray + (mc.getNetworkHandler().getPlayerListEntry(mc.player.getUuid()) == null ? 0 : mc.getNetworkHandler().getPlayerListEntry(mc.player.getUuid()).getLatency()), 2, 22, 0x55FFFF);
textRenderer.drawWithShadow(matrix, "Meters/s: " + ColorUtils.gray + round(moveSpeed(), 2), 2, scaledHeight - 20, 0x55FFFF);
// Coords
textRenderer.drawWithShadow(matrix, "X: " + ColorUtils.gray + round(mc.player.getX(), 1) +
ColorUtils.reset + " Y: " + ColorUtils.gray + round(mc.player.getY(), 1) +
ColorUtils.reset + " Z: " + ColorUtils.gray + round(mc.player.getZ(), 1), 2, scaledHeight - 10, 0x55FFFF);
}
private static double round(double value, int places)
{
if (places < 0) throw new IllegalArgumentException();
BigDecimal bd = new BigDecimal(Double.toString(value));
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
private double moveSpeed()
{
Vec3d move = new Vec3d(mc.player.getX() - mc.player.prevX, 0, mc.player.getZ() - mc.player.prevZ).multiply(20);
return Math.abs(length2D(move)) ;
}
public double length2D(Vec3d vec3d)
{
return MathHelper.sqrt((float)(vec3d.x * vec3d.x + vec3d.z * vec3d.z));
}
}

View file

@ -1,4 +1,4 @@
package me.kawaiizenbo.moonlight.ui;
package me.kawaiizenbo.moonlight.ui.altmanager;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;

View file

@ -0,0 +1,14 @@
package me.kawaiizenbo.moonlight.ui.clickgui;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
public class ClickGUIScreen extends Screen
{
public static ClickGUIScreen INSTANCE = new ClickGUIScreen(null);
protected ClickGUIScreen(Text title)
{
super(title);
}
}

View file

@ -1,6 +1,29 @@
package me.kawaiizenbo.moonlight.util;
import org.jetbrains.annotations.Nullable;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
public class ChatUtils
{
private static MinecraftClient mc = MinecraftClient.getInstance();
public static void sendMsg(String message)
{
sendMsg(null, null, Text.literal(message));
}
public static void sendMsg(@Nullable String prefixTitle, @Nullable Formatting prefixColor, Text msg)
{
if (mc.world == null) return;
//Text message = Text.literal("");
//message.append(CommandManager.get().getPrefix());
//if (prefixTitle != null) message.append(CommandManager.get().getPrefix());
//message.append(msg);
mc.inGameHud.getChatHud().addMessage(msg);
}
}

View file

@ -21,10 +21,10 @@ public class ColorUtils
public static String yellow = "\247e";
public static String white = "\247f";
public static String underline = "\247u";
public static String underline = "\247n";
public static String bold = "\247l";
public static String italic = "\247o";
public static String strikethrough = "\247m";
public static String cipher = "\247k";
public static String obfuscated = "\247k";
public static String reset = "\247r";
}

View file

@ -6,7 +6,8 @@
"name": "Moonlight Meadows",
"description": "Utility mod with a focus on stability.",
"authors": [
"KawaiiZenbo"
"KawaiiZenbo",
"BadGamesInc"
],
"contact": {
"homepage": "https://kawaiizenbo.me/",

View file

@ -7,7 +7,10 @@
],
"client": [
"TitleScreenMixin",
"MultiplayerScreenMixin"
"MultiplayerScreenMixin",
"InGameHUDMixin",
"ChatInputSuggestorMixin",
"ClientConnectionMixin"
],
"injectors": {
"defaultRequire": 1