feat: use mojang mappings

refactor: add null checks to some things
This commit is contained in:
Chayapak Supasakul 2025-12-29 11:41:15 +07:00
parent 4142d41d64
commit 164d5ca388
Signed by: ChomeNS
SSH key fingerprint: SHA256:0YoxhdyXsgbc0nfeB2N6FYE60mxMU7DS4uCUMaw2mvA
61 changed files with 947 additions and 966 deletions

View file

@ -1,5 +1,5 @@
plugins {
id 'fabric-loom' version "${loom_version}"
id 'fabric-loom' version "${loom_version}"
}
base.archivesName = project.archives_base_name
@ -7,56 +7,56 @@ version = project.mod_version
group = project.maven_group
repositories {
mavenCentral()
mavenCentral()
// adventure snapshots
maven {
url = "https://s01.oss.sonatype.org/content/repositories/snapshots/"
mavenContent { snapshotsOnly() }
}
// adventure snapshots
maven {
url = "https://s01.oss.sonatype.org/content/repositories/snapshots/"
mavenContent { snapshotsOnly() }
}
}
dependencies {
// To change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
// To change the versions see the gradle.properties file
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings loom.officialMojangMappings()
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
// Fabric API
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
// Fabric API
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
// LuaJ
include(implementation("org.luaj:luaj-jse:3.0.1"))
// LuaJ
include(implementation("org.luaj:luaj-jse:3.0.1"))
// Configurate
include(implementation("org.spongepowered:configurate-core:4.2.0"))
include(implementation("org.spongepowered:configurate-gson:4.2.0"))
include(implementation("io.leangen.geantyref:geantyref:2.0.1"))
// Configurate
include(implementation("org.spongepowered:configurate-core:4.2.0"))
include(implementation("org.spongepowered:configurate-gson:4.2.0"))
include(implementation("io.leangen.geantyref:geantyref:2.0.1"))
// Adventure
include(modImplementation("net.kyori:adventure-platform-fabric:6.8.0"))
include(implementation("net.kyori:adventure-text-serializer-gson:4.26.1"))
include(implementation("net.kyori:adventure-text-serializer-legacy:4.26.1"))
// Adventure
include(modImplementation("net.kyori:adventure-platform-fabric:6.8.0"))
include(implementation("net.kyori:adventure-text-serializer-gson:4.26.1"))
include(implementation("net.kyori:adventure-text-serializer-legacy:4.26.1"))
}
processResources {
inputs.property "version", project.version
inputs.property "version", project.version
filesMatching("fabric.mod.json") {
expand "version": project.version
}
filesMatching("fabric.mod.json") {
expand "version": project.version
}
}
tasks.withType(JavaCompile).configureEach {
// Minecraft 1.18 (1.18-pre2) upwards uses Java 17.
it.options.release = 21
// Minecraft 1.18 (1.18-pre2) upwards uses Java 17.
it.options.release = 21
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
jar {
from("LICENSE") {
rename { "${it}_${base.archivesName}"}
}
from("LICENSE") {
rename { "${it}_${base.archivesName}" }
}
}

View file

@ -5,7 +5,6 @@ org.gradle.parallel=true
# Fabric Properties
# check these on https://fabricmc.net/develop
minecraft_version=1.21.11
yarn_mappings=1.21.11+build.3
loader_version=0.18.3
loom_version=1.13-SNAPSHOT

View file

@ -7,21 +7,21 @@ import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import land.chipmunk.chipmunkmod.commands.*;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.command.CommandRegistryAccess;
import net.minecraft.text.ClickEvent;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.text.Texts;
import net.minecraft.util.Formatting;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.network.chat.ClickEvent;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ComponentUtils;
import net.minecraft.network.chat.MutableComponent;
public class CommandManager {
public static CommandManager INSTANCE;
public CommandDispatcher<FabricClientCommandSource> dispatcher = new CommandDispatcher<>();
public String prefix;
public CommandManager (final String prefix, final CommandRegistryAccess commandRegistryAccess) {
public CommandManager (final String prefix, final CommandBuildContext commandRegistryAccess) {
this.prefix = prefix;
TestCommand.register(this.dispatcher);
@ -50,45 +50,45 @@ public class CommandManager {
}
public void executeCommand (final String command) {
final MinecraftClient client = MinecraftClient.getInstance();
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
final Minecraft client = Minecraft.getInstance();
final ClientPacketListener networkHandler = client.getConnection();
if (networkHandler == null) return;
final FabricClientCommandSource commandSource = (FabricClientCommandSource) networkHandler.getCommandSource();
final FabricClientCommandSource commandSource = (FabricClientCommandSource) networkHandler.getSuggestionsProvider();
try {
dispatcher.execute(command, commandSource);
} catch (final CommandSyntaxException e) {
commandSource.sendError(Texts.toText(e.getRawMessage()));
final Text context = getContext(e);
commandSource.sendError(ComponentUtils.fromMessage(e.getRawMessage()));
final Component context = getContext(e);
if (context != null) commandSource.sendError(context);
} catch (final Exception e) {
commandSource.sendError(Text.of(e.getMessage()));
commandSource.sendError(Component.nullToEmpty(e.getMessage()));
}
}
public Text getContext (final CommandSyntaxException exception) {
public Component getContext (final 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);
final MutableComponent text = Component.literal("")
.withStyle(ChatFormatting.GRAY);
text.setStyle(text.getStyle().withClickEvent(new ClickEvent.SuggestCommand(prefix + input)));
final int cursor = Math.min(input.length(), _cursor);
if (cursor > CommandSyntaxException.CONTEXT_AMOUNT) {
text.append(Text.literal("..."));
text.append(Component.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));
.append(Component.literal(input.substring(Math.max(0, cursor - CommandSyntaxException.CONTEXT_AMOUNT), cursor)))
.append(Component.literal(input.substring(cursor)).withStyle(ChatFormatting.RED, ChatFormatting.UNDERLINE))
.append(Component.translatable("command.context.here").withStyle(ChatFormatting.RED, ChatFormatting.ITALIC));
return text;
}

View file

@ -5,8 +5,6 @@ import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import net.minecraft.text.Text;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
@ -14,6 +12,7 @@ import java.net.URL;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import net.minecraft.network.chat.Component;
public class LocationArgumentType implements ArgumentType<Object> {
private static final Collection<String> EXAMPLES = Arrays.asList("songs/amogus.mid", "images/cat.jpg", "videos/badapple.mp4");
@ -74,7 +73,7 @@ public class LocationArgumentType implements ArgumentType<Object> {
try {
return new URI(sb.toString()).toURL();
} catch (final MalformedURLException | URISyntaxException exception) {
throw new SimpleCommandExceptionType(Text.literal(exception.getMessage())).create();
throw new SimpleCommandExceptionType(Component.literal(exception.getMessage())).create();
}
}

View file

@ -5,7 +5,7 @@ import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import land.chipmunk.chipmunkmod.modules.SelfCare;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.text.Text;
import net.minecraft.network.chat.Component;
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
import static com.mojang.brigadier.arguments.StringArgumentType.string;
@ -31,10 +31,10 @@ public class AutoSkinCommand {
SelfCare.INSTANCE.targetSkin = username;
if (username.equals("off")) {
source.sendFeedback(Text.literal("Successfully disabled auto skin"));
source.sendFeedback(Component.literal("Successfully disabled auto skin"));
} else {
SelfCare.INSTANCE.hasSkin = false;
source.sendFeedback(Text.literal("Set your auto skin username to: " + username));
source.sendFeedback(Component.literal("Set your auto skin username to: " + username));
}
return Command.SINGLE_SUCCESS;

View file

@ -7,7 +7,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import land.chipmunk.chipmunkmod.modules.CommandLoopManager;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.text.Text;
import net.minecraft.network.chat.Component;
import java.util.List;
@ -21,36 +21,23 @@ import static land.chipmunk.chipmunkmod.command.CommandManager.argument;
import static land.chipmunk.chipmunkmod.command.CommandManager.literal;
public class CloopCommand {
private static final DynamicCommandExceptionType INVALID_CLOOP_ID_EXCEPTION = new DynamicCommandExceptionType(id -> Text.translatable("Invalid cloop id: %s", Text.literal(String.valueOf(id))));
private static final DynamicCommandExceptionType INVALID_CLOOP_ID_EXCEPTION = new DynamicCommandExceptionType(id -> Component.translatable("Invalid cloop id: %s", Component.literal(String.valueOf(id))));
public static void register (final CommandDispatcher<FabricClientCommandSource> dispatcher) {
dispatcher.register(
literal("cloop")
.then(
literal("add")
.then(
argument("interval", longArg())
.then(
argument("command", greedyString())
.executes(c -> addCloop(c))
)
)
)
.then(
literal("remove")
.then(
argument("id", integer())
.executes(c -> removeCloop(c))
)
)
.then(
literal("clear")
.executes(c -> clearCloops(c))
)
.then(
literal("list")
.executes(c -> listCloops(c))
.then(literal("add")
.then(argument("interval", longArg())
.then(argument("command", greedyString())
.executes(CloopCommand::addCloop)
)
)
)
.then(literal("remove")
.then(argument("id", integer())
.executes(CloopCommand::removeCloop)))
.then(literal("clear").executes(CloopCommand::clearCloops))
.then(literal("list").executes(CloopCommand::listCloops))
);
}
@ -61,7 +48,7 @@ public class CloopCommand {
final int id = CommandLoopManager.INSTANCE.loopCommand(command, interval);
source.sendFeedback(Text.translatable("Successfully created a loop for command '%s' with id %s", Text.literal(command), Text.literal(String.valueOf(id))));
source.sendFeedback(Component.translatable("Successfully created a loop for command '%s' with id %s", Component.literal(command), Component.literal(String.valueOf(id))));
return Command.SINGLE_SUCCESS;
}
@ -74,7 +61,7 @@ public class CloopCommand {
manager.removeAndStop(id);
source.sendFeedback(Text.translatable("Successfully removed loop with id %s", Text.literal(String.valueOf(id))));
source.sendFeedback(Component.translatable("Successfully removed loop with id %s", Component.literal(String.valueOf(id))));
return Command.SINGLE_SUCCESS;
}
@ -84,7 +71,7 @@ public class CloopCommand {
manager.clearLoops();
source.sendFeedback(Text.translatable("Successfully cleared all command loops"));
source.sendFeedback(Component.translatable("Successfully cleared all command loops"));
return Command.SINGLE_SUCCESS;
}
@ -94,12 +81,12 @@ public class CloopCommand {
int id = 0;
for (final CommandLoopManager.CommandLoop loop : loops) {
source.sendFeedback(Text.translatable("%s: %s (%s)", Text.literal(String.valueOf(id)), Text.literal(loop.command), Text.literal(String.valueOf(loop.interval))));
source.sendFeedback(Component.translatable("%s: %s (%s)", Component.literal(String.valueOf(id)), Component.literal(loop.command), Component.literal(String.valueOf(loop.interval))));
id++;
}
if (id == 0) {
source.sendFeedback(Text.translatable("No command loops are currently running"));
source.sendFeedback(Component.translatable("No command loops are currently running"));
}
return Command.SINGLE_SUCCESS;

View file

@ -3,12 +3,13 @@ package land.chipmunk.chipmunkmod.commands;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import land.chipmunk.chipmunkmod.ChipmunkMod;
import land.chipmunk.chipmunkmod.modules.CommandCore;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.text.Text;
import net.minecraft.text.TextCodecs;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ComponentSerialization;
import java.util.concurrent.CompletableFuture;
import static com.mojang.brigadier.arguments.BoolArgumentType.bool;
@ -26,7 +27,7 @@ public class CoreCommand {
literal("run")
.then(
argument("command", greedyString())
.executes(c -> run(c))
.executes(CoreCommand::run)
)
)
@ -34,18 +35,18 @@ public class CoreCommand {
literal("runTracked")
.then(
argument("command", greedyString())
.executes(c -> runTracked(c))
.executes(CoreCommand::runTracked)
)
)
.then(literal("refill").executes(c -> refill(c)))
.then(literal("move").executes(c -> move(c)))
.then(literal("refill").executes(CoreCommand::refill))
.then(literal("move").executes(CoreCommand::move))
.then(
literal("runFillCommand")
.then(
argument("enabled", bool())
.executes(c -> runFillCommand(c))
.executes(CoreCommand::runFillCommand)
)
)
);
@ -62,14 +63,14 @@ public class CoreCommand {
final String command = getString(context, "command");
final CompletableFuture<NbtCompound> future = CommandCore.INSTANCE.runTracked(command);
final CompletableFuture<CompoundTag> future = CommandCore.INSTANCE.runTracked(command);
future.thenApply(tag -> {
if (tag == null) return null;
try {
tag.get("LastOutput", TextCodecs.CODEC).ifPresent(source::sendFeedback);
} catch (final Exception e) {
e.printStackTrace();
tag.read("LastOutput", ComponentSerialization.CODEC).ifPresent(source::sendFeedback);
} catch (final Throwable throwable) {
ChipmunkMod.LOGGER.error("Failed to read LastOutput", throwable);
}
return tag;
@ -87,7 +88,8 @@ public class CoreCommand {
public static int move (final CommandContext<FabricClientCommandSource> context) {
final FabricClientCommandSource source = context.getSource();
CommandCore.INSTANCE.move(source.getClient().player.getEyePos());
final LocalPlayer player = source.getClient().player;
if (player != null) CommandCore.INSTANCE.move(player.getEyePosition());
return Command.SINGLE_SUCCESS;
}
@ -99,7 +101,7 @@ public class CoreCommand {
CommandCore.INSTANCE.runFillCommand = bool;
source.sendFeedback(Text.literal("Running fill commands is now " + (bool ? "enabled" : "disabled")));
source.sendFeedback(Component.literal("Running fill commands is now " + (bool ? "enabled" : "disabled")));
return Command.SINGLE_SUCCESS;
}

View file

@ -7,7 +7,7 @@ import land.chipmunk.chipmunkmod.ChipmunkMod;
import land.chipmunk.chipmunkmod.modules.custom_chat.CustomChat;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.minecraft.text.Text;
import net.minecraft.network.chat.Component;
import static com.mojang.brigadier.arguments.BoolArgumentType.bool;
import static com.mojang.brigadier.arguments.BoolArgumentType.getBool;
@ -50,7 +50,7 @@ public class CustomChatCommand {
final FabricClientCommandSource source = context.getSource();
final boolean bool = getBool(context, "boolean");
CustomChat.INSTANCE.enabled = bool;
source.sendFeedback(Text.literal("Custom chat is now " + (bool ? "on" : "off")));
source.sendFeedback(Component.literal("Custom chat is now " + (bool ? "on" : "off")));
return Command.SINGLE_SUCCESS;
}
@ -60,8 +60,8 @@ public class CustomChatCommand {
final boolean bool = getBool(context, "boolean");
CustomChat.INSTANCE.onlyUseWhenNecessary = bool;
if (bool) source.sendFeedback(Text.literal("Custom chat now only gets used when necessary"));
else source.sendFeedback(Text.literal("Custom chat now always get used"));
if (bool) source.sendFeedback(Component.literal("Custom chat now only gets used when necessary"));
else source.sendFeedback(Component.literal("Custom chat now always get used"));
return Command.SINGLE_SUCCESS;
}
@ -70,7 +70,7 @@ public class CustomChatCommand {
final FabricClientCommandSource source = context.getSource();
final String format = getString(context, "format");
CustomChat.INSTANCE.format = GSON.deserializeOr(format, ChipmunkMod.CONFIG.customChat.format);
source.sendFeedback(Text.literal("Set the custom chat format to: " + format));
source.sendFeedback(Component.literal("Set the custom chat format to: " + format));
return Command.SINGLE_SUCCESS;
}

View file

@ -4,9 +4,9 @@ import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component;
import org.luaj.vm2.Globals;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.lib.jse.CoerceJavaToLua;
@ -21,10 +21,8 @@ public class EvalCommand {
public static void register (final CommandDispatcher<FabricClientCommandSource> dispatcher) {
dispatcher.register(
literal("eval")
.then(
argument("code", greedyString())
.executes(EvalCommand::eval)
)
.then(argument("code", greedyString())
.executes(EvalCommand::eval))
);
}
@ -34,15 +32,15 @@ public class EvalCommand {
try {
final Globals globals = JsePlatform.standardGlobals();
globals.set("client", CoerceJavaToLua.coerce(MinecraftClient.getInstance()));
globals.set("client", CoerceJavaToLua.coerce(Minecraft.getInstance()));
globals.set("context", CoerceJavaToLua.coerce(context));
globals.set("class", CoerceJavaToLua.coerce(Class.class));
final LuaValue chunk = globals.load(code);
context.getSource().sendFeedback(Text.literal(chunk.call().toString()).formatted(Formatting.GREEN));
context.getSource().sendFeedback(Component.literal(chunk.call().toString()).withStyle(ChatFormatting.GREEN));
} catch (final Exception e) {
context.getSource().sendError(Text.literal(e.toString()));
context.getSource().sendError(Component.literal(e.toString()));
}
return Command.SINGLE_SUCCESS;

View file

@ -5,30 +5,30 @@ import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.client.MinecraftClient;
import net.minecraft.command.CommandRegistryAccess;
import net.minecraft.item.ItemStack;
import net.minecraft.network.packet.c2s.play.CreativeInventoryActionC2SPacket;
import net.minecraft.text.Text;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ServerboundSetCreativeModeSlotPacket;
import net.minecraft.world.item.ItemStack;
import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
import static land.chipmunk.chipmunkmod.command.CommandManager.argument;
import static land.chipmunk.chipmunkmod.command.CommandManager.literal;
import static net.minecraft.command.argument.ItemStackArgumentType.getItemStackArgument;
import static net.minecraft.command.argument.ItemStackArgumentType.itemStack;
import static net.minecraft.commands.arguments.item.ItemArgument.getItem;
import static net.minecraft.commands.arguments.item.ItemArgument.item;
public class ItemCommand {
public static void register (final CommandDispatcher<FabricClientCommandSource> dispatcher, final CommandRegistryAccess commandRegistryAccess) {
public static void register (final CommandDispatcher<FabricClientCommandSource> dispatcher, final CommandBuildContext commandRegistryAccess) {
dispatcher.register(
literal("item")
.then(
argument("item", itemStack(commandRegistryAccess))
argument("item", item(commandRegistryAccess))
.executes(c -> setItem(c, 1))
.then(
argument("count", integer(1, 64))
.executes(c -> setItem(c))
)
.then(argument("count", integer(1, 64))
.executes(ItemCommand::setItem))
)
);
}
@ -39,19 +39,23 @@ public class ItemCommand {
public static int setItem (final CommandContext<FabricClientCommandSource> context, final int count) throws CommandSyntaxException {
final FabricClientCommandSource source = context.getSource();
final MinecraftClient client = source.getClient();
final Minecraft client = source.getClient();
final ItemStack stack = getItemStackArgument(context, "item").createStack(count, false);
final LocalPlayer player = client.player;
final ClientPacketListener connection = client.getConnection();
final int slot = 36 + client.player.getInventory().getSelectedSlot();
if (player == null || connection == null) return Command.SINGLE_SUCCESS;
client.getNetworkHandler().getConnection().send(new CreativeInventoryActionC2SPacket(slot, stack));
final ItemStack stack = getItem(context, "item").createItemStack(count, false);
final int slot = 36 + player.getInventory().getSelectedSlot();
connection.send(new ServerboundSetCreativeModeSlotPacket(slot, stack));
source.sendFeedback(
Text.translatable(
Component.translatable(
"Replaced your held item with %s %s",
Text.literal(String.valueOf(count)),
stack.toHoverableText()
Component.literal(String.valueOf(count)),
stack.getDisplayName()
)
);
return Command.SINGLE_SUCCESS;

View file

@ -13,9 +13,9 @@ import net.kyori.adventure.text.JoinConfiguration;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minecraft.client.MinecraftClient;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
import java.io.File;
import java.nio.file.Path;
@ -35,9 +35,9 @@ import static land.chipmunk.chipmunkmod.command.arguments.LocationArgumentType.*
import static land.chipmunk.chipmunkmod.command.arguments.TimestampArgumentType.timestamp;
public class MusicCommand {
private static final SimpleCommandExceptionType NO_SONG_IS_CURRENTLY_PLAYING = new SimpleCommandExceptionType(Text.translatable("No song is currently playing"));
private static final SimpleCommandExceptionType OOB_TIMESTAMP = new SimpleCommandExceptionType(Text.translatable("Invalid timestamp for the current song"));
private static final SimpleCommandExceptionType DIRECTORY_DOES_NOT_EXIST = new SimpleCommandExceptionType(Text.translatable("The specified directory does not exist"));
private static final SimpleCommandExceptionType NO_SONG_IS_CURRENTLY_PLAYING = new SimpleCommandExceptionType(net.minecraft.network.chat.Component.translatable("No song is currently playing"));
private static final SimpleCommandExceptionType OOB_TIMESTAMP = new SimpleCommandExceptionType(net.minecraft.network.chat.Component.translatable("Invalid timestamp for the current song"));
private static final SimpleCommandExceptionType DIRECTORY_DOES_NOT_EXIST = new SimpleCommandExceptionType(net.minecraft.network.chat.Component.translatable("The specified directory does not exist"));
public static void register (final CommandDispatcher<FabricClientCommandSource> dispatcher) {
final MusicCommand instance = new MusicCommand();
@ -129,7 +129,7 @@ public class MusicCommand {
songPlayer.stopPlaying();
songPlayer.songQueue.clear();
source.sendFeedback(Text.literal("Stopped music playback").formatted(Formatting.GREEN));
source.sendFeedback(net.minecraft.network.chat.Component.literal("Stopped music playback").withStyle(ChatFormatting.GREEN));
return 1;
}
@ -141,7 +141,7 @@ public class MusicCommand {
if (songPlayer.currentSong == null) throw NO_SONG_IS_CURRENTLY_PLAYING.create();
songPlayer.stopPlaying();
source.sendFeedback(Text.literal("Skipped the current song").formatted(Formatting.GREEN));
source.sendFeedback(net.minecraft.network.chat.Component.literal("Skipped the current song").withStyle(ChatFormatting.GREEN));
return 1;
}
@ -155,10 +155,10 @@ public class MusicCommand {
if (!currentSong.paused) {
currentSong.pause();
source.sendFeedback(Text.literal("Paused the current song"));
source.sendFeedback(net.minecraft.network.chat.Component.literal("Paused the current song"));
} else {
currentSong.play();
source.sendFeedback(Text.literal("Unpaused the current song"));
source.sendFeedback(net.minecraft.network.chat.Component.literal("Unpaused the current song"));
}
return 1;
@ -220,7 +220,8 @@ public class MusicCommand {
mergedList.addAll(files);
final Component component = Component.translatable("Songs - %s", Component.join(JoinConfiguration.separator(Component.space()), mergedList)).color(NamedTextColor.GREEN);
MinecraftClient.getInstance().player.sendMessage(component);
final LocalPlayer player = Minecraft.getInstance().player;
if (player != null) player.sendMessage(component);
return 1;
}
@ -247,7 +248,7 @@ public class MusicCommand {
currentSong.looping = !currentSong.looping;
source.sendFeedback(Text.translatable(currentSong.looping ? "Enabled looping" : "Disabled looping"));
source.sendFeedback(net.minecraft.network.chat.Component.translatable(currentSong.looping ? "Enabled looping" : "Disabled looping"));
return 1;
}
@ -264,13 +265,12 @@ public class MusicCommand {
currentSong.looping = true;
currentSong.loopCount = count;
source.sendFeedback(Text.translatable("Enabled looping for %s times", Text.literal(String.valueOf(count))));
source.sendFeedback(net.minecraft.network.chat.Component.translatable("Enabled looping for %s times", net.minecraft.network.chat.Component.literal(String.valueOf(count))));
return 1;
}
public int gotoCommand (final CommandContext<FabricClientCommandSource> context) throws CommandSyntaxException {
final FabricClientCommandSource source = context.getSource();
final SongPlayer songPlayer = SongPlayer.INSTANCE;
final Song currentSong = songPlayer.currentSong;
final long millis = getLong(context, "timestamp");
@ -281,7 +281,8 @@ public class MusicCommand {
currentSong.setTime(millis);
MinecraftClient.getInstance().player.sendMessage(Component.translatable("Set the current time of the song to %s", songPlayer.formatTime(millis)));
final LocalPlayer player = Minecraft.getInstance().player;
if (player != null) player.sendMessage(Component.translatable("Set the current time of the song to %s", songPlayer.formatTime(millis)));
return 1;
}
@ -293,7 +294,7 @@ public class MusicCommand {
SongPlayer.INSTANCE.useCore = enabled;
source.sendFeedback(Text.literal("Playing music using core is now " + (enabled ? "enabled" : "disabled")));
source.sendFeedback(net.minecraft.network.chat.Component.literal("Playing music using core is now " + (enabled ? "enabled" : "disabled")));
return 1;
}
@ -305,7 +306,7 @@ public class MusicCommand {
SongPlayer.INSTANCE.actionbar = enabled;
source.sendFeedback(Text.literal("Showing actionbar is now " + (enabled ? "enabled" : "disabled")));
source.sendFeedback(net.minecraft.network.chat.Component.literal("Showing actionbar is now " + (enabled ? "enabled" : "disabled")));
return 1;
}
@ -318,10 +319,10 @@ public class MusicCommand {
SongPlayer.INSTANCE.pitch = pitch;
source.sendFeedback(
Text.translatable(
net.minecraft.network.chat.Component.translatable(
"Set the pitch to: %s",
Text.literal(String.valueOf(pitch))
).formatted(Formatting.GREEN)
net.minecraft.network.chat.Component.literal(String.valueOf(pitch))
).withStyle(ChatFormatting.GREEN)
);
return 1;

View file

@ -6,7 +6,7 @@ import com.mojang.brigadier.context.CommandContext;
import land.chipmunk.chipmunkmod.ChipmunkMod;
import land.chipmunk.chipmunkmod.command.CommandManager;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.text.Text;
import net.minecraft.network.chat.Component;
import static com.mojang.brigadier.arguments.StringArgumentType.*;
import static land.chipmunk.chipmunkmod.command.CommandManager.argument;
@ -31,7 +31,7 @@ public class PrefixCommand {
ChipmunkMod.CONFIG.commands.prefix = prefix;
CommandManager.INSTANCE.prefix = prefix;
source.sendFeedback(Text.literal("Set the command prefix to: " + prefix));
source.sendFeedback(Component.literal("Set the command prefix to: " + prefix));
return Command.SINGLE_SUCCESS;
}

View file

@ -5,7 +5,7 @@ import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import land.chipmunk.chipmunkmod.modules.RainbowName;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.text.Text;
import net.minecraft.network.chat.Component;
import static com.mojang.brigadier.arguments.BoolArgumentType.bool;
import static com.mojang.brigadier.arguments.BoolArgumentType.getBool;
@ -18,20 +18,12 @@ public class RainbowNameCommand {
public static void register (final CommandDispatcher<FabricClientCommandSource> dispatcher) {
dispatcher.register(
literal("rainbowname")
.then(
literal("enabled")
.then(
argument("boolean", bool())
.executes(RainbowNameCommand::enabled)
)
)
.then(
literal("setName")
.then(
argument("name", greedyString())
.executes(RainbowNameCommand::setName)
)
)
.then(literal("enabled")
.then(argument("boolean", bool())
.executes(RainbowNameCommand::enabled)))
.then(literal("setName")
.then(argument("name", greedyString())
.executes(RainbowNameCommand::setName)))
);
}
@ -42,10 +34,10 @@ public class RainbowNameCommand {
if (bool) {
RainbowName.INSTANCE.enable();
source.sendFeedback(Text.literal("Rainbow name is now enabled"));
source.sendFeedback(Component.literal("Rainbow name is now enabled"));
} else {
RainbowName.INSTANCE.disable();
source.sendFeedback(Text.literal("Rainbow name is now disabled"));
source.sendFeedback(Component.literal("Rainbow name is now disabled"));
}
return Command.SINGLE_SUCCESS;
@ -58,7 +50,7 @@ public class RainbowNameCommand {
RainbowName.INSTANCE.displayName = name;
source.sendFeedback(Text.literal("Set the display name to: " + name));
source.sendFeedback(Component.literal("Set the display name to: " + name));
return Command.SINGLE_SUCCESS;
}

View file

@ -7,8 +7,7 @@ import land.chipmunk.chipmunkmod.ChipmunkMod;
import land.chipmunk.chipmunkmod.modules.CommandCore;
import land.chipmunk.chipmunkmod.modules.custom_chat.CustomChat;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.text.Text;
import net.minecraft.network.chat.Component;
import java.io.IOException;
import static land.chipmunk.chipmunkmod.command.CommandManager.literal;
@ -30,9 +29,9 @@ public class ReloadConfigCommand {
CommandCore.INSTANCE.reloadFromConfig();
CustomChat.INSTANCE.reloadFromConfig();
source.sendFeedback(Text.literal("Successfully reloaded the config"));
source.sendFeedback(Component.literal("Successfully reloaded the config"));
} catch (final IOException e) {
source.sendError(Text.literal("Could not load config, check the logs for stacktrace"));
source.sendError(Component.literal("Could not load config, check the logs for stacktrace"));
ChipmunkMod.LOGGER.error("Could not load the config!", e);
}

View file

@ -5,7 +5,7 @@ import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import land.chipmunk.chipmunkmod.modules.SelfCare;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.text.Text;
import net.minecraft.network.chat.Component;
import static com.mojang.brigadier.arguments.BoolArgumentType.bool;
import static com.mojang.brigadier.arguments.BoolArgumentType.getBool;
@ -47,15 +47,15 @@ public class SelfCareCommand {
switch (type) {
case "op" -> {
SelfCare.INSTANCE.configOpEnabled = bool;
source.sendFeedback(Text.literal("The op self care is now " + (bool ? "enabled" : "disabled")));
source.sendFeedback(Component.literal("The op self care is now " + (bool ? "enabled" : "disabled")));
}
case "gamemode" -> {
SelfCare.INSTANCE.configGameModeEnabled = bool;
source.sendFeedback(Text.literal("The gamemode self care is now " + (bool ? "enabled" : "disabled")));
source.sendFeedback(Component.literal("The gamemode self care is now " + (bool ? "enabled" : "disabled")));
}
case "cspy" -> {
SelfCare.INSTANCE.configCommandSpyEnabled = bool;
source.sendFeedback(Text.literal("The CommandSpy self care is now " + (bool ? "enabled" : "disabled")));
source.sendFeedback(Component.literal("The CommandSpy self care is now " + (bool ? "enabled" : "disabled")));
}
}

View file

@ -4,21 +4,18 @@ import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.text.Text;
import net.minecraft.network.chat.Component;
import static land.chipmunk.chipmunkmod.command.CommandManager.literal;
public class TestCommand {
public static void register (final CommandDispatcher<FabricClientCommandSource> dispatcher) {
dispatcher.register(
literal("test")
.executes(c -> helloWorld(c))
);
dispatcher.register(literal("test").executes(TestCommand::helloWorld));
}
public static int helloWorld (final CommandContext<FabricClientCommandSource> context) {
final FabricClientCommandSource source = context.getSource();
source.sendFeedback(Text.literal("Hello, world!"));
source.sendFeedback(Component.literal("Hello, world!"));
return Command.SINGLE_SUCCESS;
}

View file

@ -5,22 +5,21 @@ import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import land.chipmunk.chipmunkmod.mixin.ClientCommonNetworkHandlerAccessor;
import land.chipmunk.chipmunkmod.mixin.MinecraftClientAccessor;
import land.chipmunk.chipmunkmod.mixin.ClientCommonPacketListenerImplAccessor;
import land.chipmunk.chipmunkmod.mixin.MinecraftAccessor;
import land.chipmunk.chipmunkmod.util.RandomUtilities;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.screen.TitleScreen;
import net.minecraft.client.gui.screen.multiplayer.ConnectScreen;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ServerAddress;
import net.minecraft.client.network.ServerInfo;
import net.minecraft.client.session.Session;
import net.minecraft.network.ClientConnection;
import net.minecraft.text.Text;
import net.minecraft.util.Uuids;
import net.minecraft.client.Minecraft;
import net.minecraft.client.User;
import net.minecraft.client.gui.screens.ConnectScreen;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.TitleScreen;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.client.multiplayer.resolver.ServerAddress;
import net.minecraft.core.UUIDUtil;
import net.minecraft.network.Connection;
import net.minecraft.network.chat.Component;
import java.util.Objects;
import java.util.Optional;
import java.util.Random;
@ -31,12 +30,12 @@ import static land.chipmunk.chipmunkmod.command.CommandManager.argument;
import static land.chipmunk.chipmunkmod.command.CommandManager.literal;
public class UsernameCommand {
private static final SimpleCommandExceptionType USERNAME_TOO_LONG = new SimpleCommandExceptionType(Text.translatable("The specified username is longer than 16 characters"));
private static final SimpleCommandExceptionType USERNAME_TOO_LONG = new SimpleCommandExceptionType(Component.translatable("The specified username is longer than 16 characters"));
private static final char[] PREMIUM_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_"
.toCharArray();
private static final char SECTION_CHAR = '§';
private static final Session ORIGINAL_SESSION = MinecraftClient.getInstance().getSession();
private static final User ORIGINAL_SESSION = Minecraft.getInstance().getUser();
private static final Random RANDOM = new Random();
public static void register (final CommandDispatcher<FabricClientCommandSource> dispatcher) {
@ -56,38 +55,38 @@ public class UsernameCommand {
);
}
private static Session offline (final String username) {
private static User offline (final String username) {
// This is how Minecraft's Main class does it
return new Session(username, Uuids.getOfflinePlayerUuid(username),
return new User(username, UUIDUtil.createOfflinePlayerUUID(username),
"", Optional.empty(), Optional.empty());
}
// TODO: Put this in a separate class
private static void reconnect (final MinecraftClient client) {
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
private static void reconnect (final Minecraft client) {
final ClientPacketListener networkHandler = client.getConnection();
if (networkHandler == null) return; // single-player?
final ServerInfo info = networkHandler.getServerInfo();
final ServerData info = networkHandler.getServerData();
if (info == null) return; // definitely single-player
final ClientConnection connection = networkHandler.getConnection();
final Connection connection = networkHandler.getConnection();
final Screen screen = Objects.requireNonNullElseGet(
((ClientCommonNetworkHandlerAccessor) networkHandler).getPostDisconnectScreen(),
((ClientCommonPacketListenerImplAccessor) networkHandler).getPostDisconnectScreen(),
TitleScreen::new);
// This stuff needs to run after we close chat, otherwise it kicks us to the title screen. Don't ask me why
client.send(() -> {
connection.disconnect(Text.translatable("disconnect.transfer"));
connection.tryDisableAutoRead();
client.schedule(() -> {
connection.disconnect(Component.translatable("disconnect.transfer"));
connection.setReadOnly();
connection.handleDisconnection();
ConnectScreen.connect(screen, client, ServerAddress.parse(info.address), info, false, null);
ConnectScreen.startConnecting(screen, client, ServerAddress.parseString(info.ip), info, false, null);
});
}
private static int changeSession (final CommandContext<FabricClientCommandSource> context, final Session session) {
final MinecraftClient client = context.getSource().getClient();
((MinecraftClientAccessor) client).session(session);
private static int changeSession (final CommandContext<FabricClientCommandSource> context, final User session) {
final Minecraft client = context.getSource().getClient();
((MinecraftAccessor) client).user(session);
reconnect(client);
return Command.SINGLE_SUCCESS;

View file

@ -4,8 +4,8 @@ import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.minecraft.util.math.BlockBox;
import net.minecraft.util.math.BlockPos;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.configurate.objectmapping.ConfigSerializable;
@ -26,7 +26,7 @@ public class Configuration {
@ConfigSerializable
public static class CommandCore {
public BlockBox relativeArea = BlockBox.create(new BlockPos(0, 0, 0), new BlockPos(15, 0, 15));
public BoundingBox relativeArea = BoundingBox.fromCorners(new BlockPos(0, 0, 0), new BlockPos(15, 0, 15));
public boolean logCommands = false;
}

View file

@ -1,25 +1,25 @@
package land.chipmunk.chipmunkmod.data;
import land.chipmunk.chipmunkmod.ChipmunkMod;
import land.chipmunk.chipmunkmod.util.TextUtilities;
import net.minecraft.text.Text;
import land.chipmunk.chipmunkmod.util.ComponentUtilities;
import net.minecraft.network.chat.Component;
import org.jetbrains.annotations.Nullable;
import java.util.List;
import java.util.Objects;
public record ChomeNSBotCommand(String name, TrustLevel trustLevel, List<String> aliases) {
public static @Nullable ChomeNSBotCommand fromText (final Text component) {
final String name = TextUtilities.plainOrNull(component);
public static @Nullable ChomeNSBotCommand fromText (final Component component) {
final String name = ComponentUtilities.plainOrNull(component);
if (name == null) return null;
final List<Text> children = component.getSiblings();
final List<Component> children = component.getSiblings();
if (children.size() < 2) return null; // must have at least trust level and alias boolean
final TrustLevel trustLevel = TrustLevel.fromText(children.getFirst());
if (trustLevel == null) return null;
final String hasAliasesString = TextUtilities.plainOrNull(children.get(1));
final String hasAliasesString = ComponentUtilities.plainOrNull(children.get(1));
if (hasAliasesString == null) return null;
final boolean hasAliases = Boolean.parseBoolean(hasAliasesString);
@ -28,7 +28,7 @@ public record ChomeNSBotCommand(String name, TrustLevel trustLevel, List<String>
final List<String> aliases = children.stream()
.skip(2)
.map(TextUtilities::plainOrNull)
.map(ComponentUtilities::plainOrNull)
.filter(Objects::nonNull)
.toList();
return new ChomeNSBotCommand(
@ -41,8 +41,8 @@ public record ChomeNSBotCommand(String name, TrustLevel trustLevel, List<String>
ADMIN,
OWNER;
public static TrustLevel fromText (final Text component) {
final String trustLevelString = TextUtilities.plainOrNull(component);
public static TrustLevel fromText (final Component component) {
final String trustLevelString = ComponentUtilities.plainOrNull(component);
if (trustLevelString == null) return null;
try {

View file

@ -1,24 +1,24 @@
package land.chipmunk.chipmunkmod.data;
import com.mojang.authlib.GameProfile;
import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
import net.minecraft.text.Text;
import net.minecraft.world.GameMode;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket;
import net.minecraft.world.level.GameType;
public class MutablePlayerListEntry {
public GameProfile profile;
public GameMode gamemode;
public GameType gamemode;
public int latency;
public Text displayName;
public Component displayName;
public MutablePlayerListEntry (final GameProfile profile, final GameMode gamemode, final int latency, final Text displayName) {
public MutablePlayerListEntry (final GameProfile profile, final GameType gamemode, final int latency, final Component displayName) {
this.profile = profile;
this.gamemode = gamemode;
this.latency = latency;
this.displayName = displayName;
}
public MutablePlayerListEntry (final PlayerListS2CPacket.Entry entry) {
public MutablePlayerListEntry (final ClientboundPlayerInfoUpdatePacket.Entry entry) {
this(entry.profile(), entry.gameMode(), entry.latency(), entry.displayName());
}
}

View file

@ -1,23 +1,23 @@
package land.chipmunk.chipmunkmod.listeners;
import net.minecraft.network.packet.Packet;
import net.minecraft.text.Text;
import net.minecraft.util.math.Vec3d;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.Packet;
import net.minecraft.world.phys.Vec3;
public interface Listener {
default void packetReceived (final Packet<?> packet) { }
default void packetSent (final Packet<?> packet) { }
default void chatMessageReceived (final Text message) { }
default void chatMessageReceived (final Component message) { }
default void overlayMessageReceived (final Text message) { }
default void overlayMessageReceived (final Component message) { }
default void coreReady () { }
default void coreMoved () { }
default void positionChanged (final Vec3d newPosition) { }
default void positionChanged (final Vec3 newPosition) { }
default void timeUpdate () { }
}

View file

@ -6,9 +6,9 @@ import land.chipmunk.chipmunkmod.command.CommandManager;
import land.chipmunk.chipmunkmod.data.ChomeNSBotCommand;
import land.chipmunk.chipmunkmod.modules.ChomeNSBotCommandSuggestions;
import land.chipmunk.chipmunkmod.util.BotValidationUtilities;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.ChatScreen;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.screens.ChatScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@ -27,23 +27,23 @@ import java.util.List;
@Mixin(value = ChatScreen.class)
public abstract class ChatScreenMixin {
@Shadow
protected TextFieldWidget chatField;
protected EditBox input;
// infinite chat
// can't use ModifyConstant due to VFP, see:
// https://github.com/ViaVersion/ViaFabricPlus/blob/main/src/main/java/com/viaversion/viafabricplus/injection/mixin/features/limitation/max_chat_length/MixinChatScreen.java
@Inject(method = "init", at = @At("RETURN"))
private void init (final CallbackInfo ci) {
chatField.setMaxLength(Integer.MAX_VALUE);
input.setMaxLength(Integer.MAX_VALUE);
}
@Inject(method = "sendMessage", at = @At("HEAD"), cancellable = true)
@Inject(method = "handleChatInput", at = @At("HEAD"), cancellable = true)
private void sendMessage (final String chatText, final boolean addToHistory, final CallbackInfo ci) {
final CommandManager commandManager = CommandManager.INSTANCE;
final MinecraftClient client = MinecraftClient.getInstance();
final Minecraft client = Minecraft.getInstance();
if (addToHistory) {
client.inGameHud.getChatHud().addToMessageHistory(chatText);
client.gui.getChat().addRecentChat(chatText);
}
if (ChipmunkMod.CONFIG.bots.testbot.webhookUrl != null && chatText.startsWith(ChipmunkMod.CONFIG.bots.testbot.prefix)) {
@ -60,7 +60,7 @@ public abstract class ChatScreenMixin {
final JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("username", "ChipmunkMod UwU");
jsonObject.addProperty("content", MinecraftClient.getInstance().getSession().getUsername());
jsonObject.addProperty("content", Minecraft.getInstance().getUser().getName());
final OutputStream stream = connection.getOutputStream();
stream.write(jsonObject.toString().getBytes());
@ -120,9 +120,9 @@ public abstract class ChatScreenMixin {
if (client.player == null) return;
if (chatText.startsWith("/")) {
client.player.networkHandler.sendChatCommand(chatText.substring(1));
client.player.connection.sendCommand(chatText.substring(1));
} else {
client.player.networkHandler.sendChatMessage(chatText);
client.player.connection.sendChat(chatText);
}
ci.cancel();

View file

@ -1,12 +0,0 @@
package land.chipmunk.chipmunkmod.mixin;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.network.ClientCommonNetworkHandler;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ClientCommonNetworkHandler.class)
public interface ClientCommonNetworkHandlerAccessor {
@Accessor("postDisconnectScreen")
Screen getPostDisconnectScreen ();
}

View file

@ -0,0 +1,12 @@
package land.chipmunk.chipmunkmod.mixin;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.multiplayer.ClientCommonPacketListenerImpl;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ClientCommonPacketListenerImpl.class)
public interface ClientCommonPacketListenerImplAccessor {
@Accessor("postDisconnectScreen")
Screen getPostDisconnectScreen ();
}

View file

@ -0,0 +1,12 @@
package land.chipmunk.chipmunkmod.mixin;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.multiplayer.prediction.BlockStatePredictionHandler;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ClientLevel.class)
public interface ClientLevelAccessor {
@Accessor(value = "blockStatePredictionHandler")
BlockStatePredictionHandler getBlockStatePredictionHandler ();
}

View file

@ -0,0 +1,183 @@
package land.chipmunk.chipmunkmod.mixin;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.mojang.brigadier.CommandDispatcher;
import land.chipmunk.chipmunkmod.ChipmunkMod;
import land.chipmunk.chipmunkmod.command.CommandManager;
import land.chipmunk.chipmunkmod.listeners.Listener;
import land.chipmunk.chipmunkmod.listeners.ListenerManager;
import land.chipmunk.chipmunkmod.modules.*;
import land.chipmunk.chipmunkmod.modules.custom_chat.CustomChat;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.components.DebugScreenOverlay;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.commands.CommandBuildContext;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.core.BlockPos;
import net.minecraft.core.RegistryAccess;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.contents.PlainTextContents;
import net.minecraft.network.chat.contents.TranslatableContents;
import net.minecraft.network.protocol.game.ClientboundCommandsPacket;
import net.minecraft.network.protocol.game.ClientboundLoginPacket;
import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket;
import net.minecraft.network.protocol.game.ClientboundSetTimePacket;
import net.minecraft.network.protocol.game.ClientboundSystemChatPacket;
import net.minecraft.world.flag.FeatureFlagSet;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.phys.Vec3;
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;
@Mixin(value = ClientPacketListener.class, priority = 1001)
public abstract class ClientPacketListenerMixin {
@Final
@Shadow
private FeatureFlagSet enabledFeatures;
@Final
@Shadow
private RegistryAccess.Frozen registryAccess;
@Shadow
private CommandDispatcher<SharedSuggestionProvider> commands;
@Shadow
public abstract ClientLevel getLevel ();
@Inject(method = "handleLogin", at = @At("TAIL"))
private void handleLogin (final ClientboundLoginPacket packet, final CallbackInfo ci) {
final CommandBuildContext commandRegistryAccess = CommandBuildContext.simple(this.registryAccess, this.enabledFeatures);
KaboomCheck.INSTANCE.onJoin();
CommandManager.INSTANCE = new CommandManager(ChipmunkMod.CONFIG.commands.prefix, commandRegistryAccess);
CommandCore.INSTANCE.init();
SongPlayer.INSTANCE.coreReady();
RainbowName.INSTANCE.init();
ChomeNSBotCommandSuggestions.INSTANCE.init();
}
@Inject(method = "handleCommands", at = @At("TAIL"))
private void handleCommands (final ClientboundCommandsPacket packet, final CallbackInfo ci) {
KaboomCheck.INSTANCE.onCommandTree(this.commands);
}
@Inject(
method = "handleSystemChat",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/multiplayer/chat/ChatListener;handleSystemMessage(Lnet/minecraft/network/chat/Component;Z)V"
),
cancellable = true
)
private void handleSystemChat (final ClientboundSystemChatPacket packet, final CallbackInfo ci) {
final Component message = packet.content();
if (
(
RainbowName.INSTANCE.enabled &&
(
message.getString().startsWith("Your nickname is now ") ||
message.getString().startsWith("Nickname changed.")
)
) ||
(
message.getContents() instanceof final TranslatableContents translatableTextContent &&
(
translatableTextContent.getKey().equals("advMode.setCommand.success")
|| translatableTextContent.getKey().equals("قيادة المجموعة: %s")
)
)
) {
ci.cancel();
return;
}
for (final Listener listener : ListenerManager.listeners) {
listener.chatMessageReceived(message);
}
if (
message.getSiblings().size() > 1
&& message.getSiblings().getFirst().getContents() instanceof final PlainTextContents textContent
&& textContent.text().equals(ChomeNSBotCommandSuggestions.REQUEST_SUGGESTIONS_ID)
) ci.cancel();
}
@WrapOperation(
method = "setActionBarText",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/gui/Gui;setOverlayMessage(Lnet/minecraft/network/chat/Component;Z)V"
)
)
private void setOverlayMessage (final Gui instance, final Component message, final boolean tinted, final Operation<Void> original) {
for (final Listener listener : ListenerManager.listeners) {
listener.overlayMessageReceived(message);
}
original.call(instance, message, tinted);
// checking for the ChomeNS Bot selector message doesn't really
// do much here since the message is just an empty string
// that gets sent only when you join (or the bot restarts),
// so I do not ignore them
}
@Inject(method = "sendChat", at = @At("HEAD"), cancellable = true)
private void sendChat (final String content, final CallbackInfo ci) {
if (Chat.NEXT_CHAT_PLAYER.get()) {
Chat.NEXT_CHAT_PLAYER.set(false);
return;
}
CustomChat.INSTANCE.chat(content);
ci.cancel();
}
@Inject(method = "handleMovePlayer", at = @At("TAIL"))
private void handleMovePlayer (final ClientboundPlayerPositionPacket packet, final CallbackInfo ci) {
final Vec3 position = packet.change().position();
final BlockPos origin = CommandCore.INSTANCE.origin;
if (origin == null) {
CommandCore.INSTANCE.move(position);
return;
}
final Minecraft client = Minecraft.getInstance();
final LocalPlayer player = client.player;
if (player == null) return;
final int distanceSquared = player.chunkPosition().distanceSquared(new ChunkPos(origin));
final int distance = (int) Math.sqrt(distanceSquared);
if (distance > getLevel().getServerSimulationDistance()) {
CommandCore.INSTANCE.alreadyFilled = true;
CommandCore.INSTANCE.move(position);
}
}
@Inject(method = "handleSetTime", at = @At("TAIL"))
private void handleSetTime (final ClientboundSetTimePacket packet, final CallbackInfo ci) {
for (final Listener listener : ListenerManager.listeners) listener.timeUpdate();
}
@WrapOperation(
method = "tick",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/gui/components/DebugScreenOverlay;showNetworkCharts()Z"
)
)
private boolean showNetworkCharts (final DebugScreenOverlay instance, final Operation<Boolean> original) {
return true;
}
}

View file

@ -1,179 +0,0 @@
package land.chipmunk.chipmunkmod.mixin;
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
import com.mojang.brigadier.CommandDispatcher;
import land.chipmunk.chipmunkmod.ChipmunkMod;
import land.chipmunk.chipmunkmod.command.CommandManager;
import land.chipmunk.chipmunkmod.listeners.Listener;
import land.chipmunk.chipmunkmod.listeners.ListenerManager;
import land.chipmunk.chipmunkmod.modules.*;
import land.chipmunk.chipmunkmod.modules.custom_chat.CustomChat;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.hud.DebugHud;
import net.minecraft.client.gui.hud.InGameHud;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.command.CommandRegistryAccess;
import net.minecraft.command.CommandSource;
import net.minecraft.network.packet.s2c.play.*;
import net.minecraft.registry.DynamicRegistryManager;
import net.minecraft.resource.featuretoggle.FeatureSet;
import net.minecraft.text.PlainTextContent;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableTextContent;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.Vec3d;
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;
@Mixin(value = ClientPlayNetworkHandler.class, priority = 1001)
public abstract class ClientPlayNetworkHandlerMixin {
@Final
@Shadow
private FeatureSet enabledFeatures;
@Final
@Shadow
private DynamicRegistryManager.Immutable combinedDynamicRegistries;
@Shadow
private CommandDispatcher<CommandSource> commandDispatcher;
@Shadow
public abstract ClientWorld getWorld ();
@Inject(method = "onGameJoin", at = @At("TAIL"))
private void onGameJoin (final GameJoinS2CPacket packet, final CallbackInfo ci) {
final CommandRegistryAccess commandRegistryAccess = CommandRegistryAccess.of(this.combinedDynamicRegistries, this.enabledFeatures);
KaboomCheck.INSTANCE.onJoin();
CommandManager.INSTANCE = new CommandManager(ChipmunkMod.CONFIG.commands.prefix, commandRegistryAccess);
CommandCore.INSTANCE.init();
SongPlayer.INSTANCE.coreReady();
RainbowName.INSTANCE.init();
ChomeNSBotCommandSuggestions.INSTANCE.init();
}
@Inject(method = "onCommandTree", at = @At("TAIL"))
private void onCommandTree (final CommandTreeS2CPacket packet, final CallbackInfo ci) {
KaboomCheck.INSTANCE.onCommandTree(this.commandDispatcher);
}
@Inject(
method = "onGameMessage",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/network/message/MessageHandler;onGameMessage(Lnet/minecraft/text/Text;Z)V"
),
cancellable = true
)
private void onGameMessage (final GameMessageS2CPacket packet, final CallbackInfo ci) {
final Text message = packet.content();
if (
(
RainbowName.INSTANCE.enabled &&
(
message.getString().startsWith("Your nickname is now ") ||
message.getString().startsWith("Nickname changed.")
)
) ||
(
message.getContent() instanceof final TranslatableTextContent translatableTextContent &&
(
translatableTextContent.getKey().equals("advMode.setCommand.success")
|| translatableTextContent.getKey().equals("قيادة المجموعة: %s")
)
)
) {
ci.cancel();
return;
}
for (final Listener listener : ListenerManager.listeners) {
listener.chatMessageReceived(message);
}
if (
message.getSiblings().size() > 1
&& message.getSiblings().getFirst().getContent() instanceof final PlainTextContent textContent
&& textContent.string().equals(ChomeNSBotCommandSuggestions.REQUEST_SUGGESTIONS_ID)
) ci.cancel();
}
@WrapOperation(
method = "onOverlayMessage",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/gui/hud/InGameHud;setOverlayMessage(Lnet/minecraft/text/Text;Z)V"
)
)
private void onOverlayMessage (final InGameHud instance, final Text message, final boolean tinted, final Operation<Void> original) {
for (final Listener listener : ListenerManager.listeners) {
listener.overlayMessageReceived(message);
}
original.call(instance, message, tinted);
// checking for the chomens bot selector message doesn't really
// do much here since the message is just an empty string
// that gets sent only when you join (or the bot restarts),
// so I do not ignore them
}
@Inject(method = "sendChatMessage", at = @At("HEAD"), cancellable = true)
private void sendChatMessage (final String content, final CallbackInfo ci) {
if (Chat.NEXT_CHAT_PLAYER.get()) {
Chat.NEXT_CHAT_PLAYER.set(false);
return;
}
CustomChat.INSTANCE.chat(content);
ci.cancel();
}
@Inject(method = "onPlayerPositionLook", at = @At("TAIL"))
private void setPosition (final PlayerPositionLookS2CPacket packet, final CallbackInfo ci) {
final Vec3d position = packet.change().position();
final BlockPos origin = CommandCore.INSTANCE.origin;
if (origin == null) {
CommandCore.INSTANCE.move(position);
return;
}
final MinecraftClient client = MinecraftClient.getInstance();
final ClientPlayerEntity player = client.player;
if (player == null) return;
final int distanceSquared = player.getChunkPos().getSquaredDistance(new ChunkPos(origin));
final int distance = (int) Math.sqrt(distanceSquared);
if (distance > getWorld().getSimulationDistance()) {
CommandCore.INSTANCE.alreadyFilled = true;
CommandCore.INSTANCE.move(position);
}
}
@Inject(method = "onWorldTimeUpdate", at = @At("TAIL"))
private void onWorldTimeUpdate (final WorldTimeUpdateS2CPacket packet, final CallbackInfo ci) {
for (final Listener listener : ListenerManager.listeners) listener.timeUpdate();
}
@WrapOperation(
method = "tick",
at = @At(
value = "INVOKE",
target = "Lnet/minecraft/client/gui/hud/DebugHud;shouldShowPacketSizeAndPingCharts()Z"
)
)
private boolean shouldShowPacketSizeAndPingCharts (final DebugHud instance, final Operation<Boolean> original) {
return true;
}
}

View file

@ -1,44 +0,0 @@
package land.chipmunk.chipmunkmod.mixin;
import land.chipmunk.chipmunkmod.modules.CommandCore;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.World;
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;
@Mixin(ClientPlayerEntity.class)
public abstract class ClientPlayerEntityMixin extends Entity {
@Shadow
@Final
public ClientPlayNetworkHandler networkHandler;
public ClientPlayerEntityMixin (final EntityType<?> type, final World world) {
super(type, world);
}
@Inject(at = @At("TAIL"), method = "move")
public void move (final CallbackInfo ci) {
final BlockPos origin = CommandCore.INSTANCE.origin;
if (origin == null) {
CommandCore.INSTANCE.move(this.getEyePos());
return;
}
final int distanceSquared = this.getChunkPos().getSquaredDistance(new ChunkPos(origin));
final int distance = (int) Math.sqrt(distanceSquared);
if (distance > networkHandler.getWorld().getSimulationDistance()) {
CommandCore.INSTANCE.alreadyFilled = true;
CommandCore.INSTANCE.move(this.getEyePos());
}
}
}

View file

@ -1,12 +0,0 @@
package land.chipmunk.chipmunkmod.mixin;
import net.minecraft.client.network.PendingUpdateManager;
import net.minecraft.client.world.ClientWorld;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(ClientWorld.class)
public interface ClientWorldAccessor {
@Accessor(value = "pendingUpdateManager")
PendingUpdateManager getPendingUpdateManager ();
}

View file

@ -9,11 +9,11 @@ import land.chipmunk.chipmunkmod.command.CommandManager;
import land.chipmunk.chipmunkmod.data.ChomeNSBotCommand;
import land.chipmunk.chipmunkmod.modules.ChomeNSBotCommandSuggestions;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.command.CommandSource;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.commands.SharedSuggestionProvider;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
@ -25,38 +25,38 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@Mixin(net.minecraft.client.gui.screen.ChatInputSuggestor.class)
public class ChatInputSuggestorMixin {
@Mixin(net.minecraft.client.gui.components.CommandSuggestions.class)
public class CommandSuggestionsMixin {
@Mutable
@Final
@Shadow
final TextFieldWidget textField;
final EditBox input;
@Shadow
private CompletableFuture<Suggestions> pendingSuggestions;
public ChatInputSuggestorMixin () {
textField = null;
public CommandSuggestionsMixin () {
input = null;
}
@Shadow
private static int getStartOfCurrentWord (final String input) {
private static int getLastWordIndex (final String input) {
return 0;
}
@Shadow
public void show (final boolean narrateFirstSuggestion) {
public void showSuggestions (final boolean narrateFirstSuggestion) {
}
@Inject(at = @At("TAIL"), method = "refresh()V")
public void refresh (final CallbackInfo ci) {
@Inject(at = @At("TAIL"), method = "updateCommandInfo()V")
public void updateCommandInfo (final CallbackInfo ci) {
final CommandManager commandManager = CommandManager.INSTANCE;
if (this.textField == null) return;
if (this.input == null) return;
final String text = this.textField.getText();
final int cursor = this.textField.getCursor();
final String text = this.input.getValue();
final int cursor = this.input.getCursorPosition();
final ClientPlayerEntity player = MinecraftClient.getInstance().player;
final LocalPlayer player = Minecraft.getInstance().player;
final String chomeNSPrefix = ChipmunkMod.CONFIG.bots.chomens.prefix;
@ -68,34 +68,33 @@ public class ChatInputSuggestorMixin {
.map(ChomeNSBotCommand::name)
.toList();
pendingSuggestions = CommandSource.suggestMatching(
pendingSuggestions = SharedSuggestionProvider.suggest(
commands,
new SuggestionsBuilder(
textUpToCursor,
getStartOfCurrentWord(textUpToCursor)
getLastWordIndex(textUpToCursor)
)
);
pendingSuggestions.thenRun(() -> {
if (!pendingSuggestions.isDone()) return;
show(true);
showSuggestions(true);
});
} else if (cursor >= commandManager.prefix.length() && text.startsWith(commandManager.prefix)) {
final StringReader reader = new StringReader(text);
reader.setCursor(commandManager.prefix.length()); // Skip the prefix
final MinecraftClient client = MinecraftClient.getInstance();
final Minecraft client = Minecraft.getInstance();
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
final ClientPacketListener connection = client.getConnection();
if (networkHandler == null) return;
if (connection == null) return;
final CommandDispatcher<FabricClientCommandSource> dispatcher = commandManager.dispatcher;
final FabricClientCommandSource commandSource = (FabricClientCommandSource) networkHandler.getCommandSource();
final FabricClientCommandSource commandSource = (FabricClientCommandSource) connection.getSuggestionsProvider();
pendingSuggestions = dispatcher.getCompletionSuggestions(dispatcher.parse(reader, commandSource), cursor);
show(true);
showSuggestions(true);
}
}
}

View file

@ -7,16 +7,17 @@ import land.chipmunk.chipmunkmod.ChipmunkMod;
import land.chipmunk.chipmunkmod.listeners.Listener;
import land.chipmunk.chipmunkmod.listeners.ListenerManager;
import land.chipmunk.chipmunkmod.modules.SelfCare;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.network.DisconnectionInfo;
import net.minecraft.network.listener.PacketListener;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.c2s.play.RequestCommandCompletionsC2SPacket;
import net.minecraft.network.packet.s2c.play.ParticleS2CPacket;
import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket;
import net.minecraft.sound.SoundEvent;
import net.minecraft.util.Identifier;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.network.DisconnectionDetails;
import net.minecraft.network.PacketListener;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundLevelParticlesPacket;
import net.minecraft.network.protocol.game.ClientboundSoundPacket;
import net.minecraft.network.protocol.game.ServerboundCommandSuggestionPacket;
import net.minecraft.resources.Identifier;
import net.minecraft.sounds.SoundEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
@ -27,16 +28,17 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@Mixin(net.minecraft.network.ClientConnection.class)
public class ClientConnectionMixin {
@Mixin(net.minecraft.network.Connection.class)
public class ConnectionMixin {
@Unique
private static final double MAX_PARTICLES_PER_PACKET = 1000;
@Unique
private static final Pattern CUSTOM_PITCH_PATTERN = Pattern.compile(".*\\.pitch\\.(.*)");
@Inject(method = "handlePacket", at = @At("HEAD"), cancellable = true)
private static <T extends PacketListener> void handlePacket (
final Packet<T> packet,
// handle packet "genericsFtw" such advanced
@Inject(method = "genericsFtw", at = @At("HEAD"), cancellable = true)
private static <T extends PacketListener> void genericsFtw (
final Packet<@NotNull T> packet,
final PacketListener packetListener,
final CallbackInfo ci
) {
@ -44,18 +46,18 @@ public class ClientConnectionMixin {
listener.packetReceived(packet);
}
final MinecraftClient client = MinecraftClient.getInstance();
final Minecraft client = Minecraft.getInstance();
// this check is very easy to bypass in 2025
if (
packet instanceof final ParticleS2CPacket t_packet
packet instanceof final ClientboundLevelParticlesPacket t_packet
&& t_packet.getCount() > MAX_PARTICLES_PER_PACKET
) {
ci.cancel();
} else if (packet instanceof final PlaySoundS2CPacket t_packet) {
} else if (packet instanceof final ClientboundSoundPacket t_packet) {
final SoundEvent soundEvent = t_packet.getSound().value();
final Identifier sound = soundEvent.id();
final Identifier sound = soundEvent.location();
final Matcher matcher = CUSTOM_PITCH_PATTERN.matcher(sound.getPath());
@ -66,18 +68,18 @@ public class ClientConnectionMixin {
final float pitch = Float.parseFloat(stringPitch);
final ClientWorld world = client.world;
final ClientLevel world = client.level;
if (world == null) return;
final SoundEvent newSound = SoundEvent.of(
Identifier.of(
final SoundEvent newSound = SoundEvent.createVariableRangeEvent(
Identifier.fromNamespaceAndPath(
sound.getNamespace(),
sound.getPath().substring(0, sound.getPath().length() - (".pitch." + stringPitch).length())
)
);
client.execute(() -> world.playSound(
client.execute(() -> world.playSeededSound(
client.player,
t_packet.getX(),
@ -85,7 +87,7 @@ public class ClientConnectionMixin {
t_packet.getZ(),
newSound,
t_packet.getCategory(),
t_packet.getSource(),
t_packet.getVolume(),
pitch,
@ -105,16 +107,16 @@ public class ClientConnectionMixin {
}
}
@WrapMethod(method = "send(Lnet/minecraft/network/packet/Packet;Lio/netty/channel/ChannelFutureListener;Z)V")
private void sendPacket (
@WrapMethod(method = "send(Lnet/minecraft/network/protocol/Packet;Lio/netty/channel/ChannelFutureListener;Z)V")
private void send (
final Packet<?> packet,
final @Nullable ChannelFutureListener channelFutureListener,
final boolean flush,
final Operation<Void> original
) {
if (
packet instanceof final RequestCommandCompletionsC2SPacket t_packet
&& t_packet.getPartialCommand().length() > 2048
packet instanceof final ServerboundCommandSuggestionPacket t_packet
&& t_packet.getCommand().length() > 2048
) return;
for (final Listener listener : ListenerManager.listeners) {
@ -124,8 +126,8 @@ public class ClientConnectionMixin {
original.call(packet, channelFutureListener, flush);
}
@Inject(method = "disconnect(Lnet/minecraft/network/DisconnectionInfo;)V", at = @At("TAIL"))
private void disconnect (final DisconnectionInfo disconnectionInfo, final CallbackInfo ci) {
@Inject(method = "disconnect(Lnet/minecraft/network/DisconnectionDetails;)V", at = @At("TAIL"))
private void disconnect (final DisconnectionDetails disconnectionInfo, final CallbackInfo ci) {
SelfCare.INSTANCE.cleanup();
}
}

View file

@ -1,12 +1,12 @@
package land.chipmunk.chipmunkmod.mixin;
import net.minecraft.client.gui.hud.debug.chart.DebugChart;
import net.minecraft.util.profiler.log.MultiValueDebugSampleLog;
import net.minecraft.client.gui.components.debugchart.AbstractDebugChart;
import net.minecraft.util.debugchart.SampleStorage;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(DebugChart.class)
@Mixin(AbstractDebugChart.class)
public interface DebugChartAccessor {
@Accessor(value = "log")
MultiValueDebugSampleLog getLog ();
@Accessor(value = "sampleStorage")
SampleStorage getSampleStorage ();
}

View file

@ -1,12 +1,12 @@
package land.chipmunk.chipmunkmod.mixin;
import net.minecraft.client.gui.hud.DebugHud;
import net.minecraft.client.gui.hud.debug.chart.PingChart;
import net.minecraft.client.gui.components.DebugScreenOverlay;
import net.minecraft.client.gui.components.debugchart.PingDebugChart;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(DebugHud.class)
@Mixin(DebugScreenOverlay.class)
public interface DebugHudAccessor {
@Accessor(value = "pingChart")
PingChart getPingChart ();
PingDebugChart getPingChart ();
}

View file

@ -1,32 +1,32 @@
package land.chipmunk.chipmunkmod.mixin;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.particle.ElderGuardianParticle;
import net.minecraft.client.particle.Particle;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.particle.SimpleParticleType;
import net.minecraft.util.math.random.Random;
import net.minecraft.core.particles.SimpleParticleType;
import net.minecraft.util.RandomSource;
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;
@Mixin(ElderGuardianParticle.Factory.class)
public class ElderGuardianAppearanceParticleMixin {
@Mixin(ElderGuardianParticle.Provider.class)
public class ElderGuardianParticleProviderMixin {
@Inject(
method = "createParticle(Lnet/minecraft/particle/SimpleParticleType;Lnet/minecraft/client/world/ClientWorld;DDDDDDLnet/minecraft/util/math/random/Random;)Lnet/minecraft/client/particle/Particle;",
method = "createParticle(Lnet/minecraft/core/particles/SimpleParticleType;Lnet/minecraft/client/multiplayer/ClientLevel;DDDDDDLnet/minecraft/util/RandomSource;)Lnet/minecraft/client/particle/Particle;",
at = @At("RETURN"),
cancellable = true
)
private void createParticle (
final SimpleParticleType simpleParticleType,
final ClientWorld clientWorld,
final ClientLevel clientWorld,
final double d,
final double e,
final double f,
final double g,
final double h,
final double i,
final Random random,
final RandomSource random,
final CallbackInfoReturnable<Particle> cir
) {
// slash scare command

View file

@ -0,0 +1,44 @@
package land.chipmunk.chipmunkmod.mixin;
import land.chipmunk.chipmunkmod.modules.CommandCore;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level;
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;
@Mixin(LocalPlayer.class)
public abstract class LocalPlayerMixin extends Entity {
@Shadow
@Final
public ClientPacketListener connection;
public LocalPlayerMixin (final EntityType<?> type, final Level world) {
super(type, world);
}
@Inject(at = @At("TAIL"), method = "move")
public void move (final CallbackInfo ci) {
final BlockPos origin = CommandCore.INSTANCE.origin;
if (origin == null) {
CommandCore.INSTANCE.move(this.getEyePosition());
return;
}
final int distanceSquared = this.chunkPosition().distanceSquared(new ChunkPos(origin));
final int distance = (int) Math.sqrt(distanceSquared);
if (distance > connection.getLevel().getServerSimulationDistance()) {
CommandCore.INSTANCE.alreadyFilled = true;
CommandCore.INSTANCE.move(this.getEyePosition());
}
}
}

View file

@ -0,0 +1,14 @@
package land.chipmunk.chipmunkmod.mixin;
import net.minecraft.client.Minecraft;
import net.minecraft.client.User;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(Minecraft.class)
public interface MinecraftAccessor {
@Mutable
@Accessor("user")
void user (User user);
}

View file

@ -1,14 +0,0 @@
package land.chipmunk.chipmunkmod.mixin;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.session.Session;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(MinecraftClient.class)
public interface MinecraftClientAccessor {
@Mutable
@Accessor("session")
void session (Session session);
}

View file

@ -0,0 +1,16 @@
package land.chipmunk.chipmunkmod.mixin;
import net.minecraft.client.resources.sounds.SoundInstance;
import net.minecraft.client.sounds.SoundEngine;
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;
@Mixin(SoundEngine.class)
public class SoundEngineMixin {
@Inject(method = "calculatePitch", at = @At("RETURN"), cancellable = true)
private void calculatePitch (final SoundInstance sound, final CallbackInfoReturnable<Float> cir) {
cir.setReturnValue(sound.getPitch());
}
}

View file

@ -1,16 +0,0 @@
package land.chipmunk.chipmunkmod.mixin;
import net.minecraft.client.sound.SoundInstance;
import net.minecraft.client.sound.SoundSystem;
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;
@Mixin(SoundSystem.class)
public class SoundSystemMixin {
@Inject(method = "getAdjustedPitch", at = @At("RETURN"), cancellable = true)
private void getAdjustedPitch (final SoundInstance sound, final CallbackInfoReturnable<Float> cir) {
cir.setReturnValue(sound.getPitch());
}
}

View file

@ -1,16 +1,16 @@
package land.chipmunk.chipmunkmod.mixin;
import land.chipmunk.chipmunkmod.modules.custom_chat.CustomChat;
import net.minecraft.util.StringHelper;
import net.minecraft.util.StringUtil;
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;
@Mixin(StringHelper.class)
public class StringHelperMixin {
@Inject(method = "isValidChar", at = @At("RETURN"), cancellable = true)
private static void isValidChar (final int c, final CallbackInfoReturnable<Boolean> cir) {
@Mixin(StringUtil.class)
public class StringUtilMixin {
@Inject(method = "isAllowedChatCharacter", at = @At("RETURN"), cancellable = true)
private static void isAllowedChatCharacter (final int c, final CallbackInfoReturnable<Boolean> cir) {
if (!CustomChat.SHOULD_IGNORE_INVALID_CHAR.get()) {
CustomChat.SHOULD_IGNORE_INVALID_CHAR.set(true);
return;

View file

@ -1,7 +1,7 @@
package land.chipmunk.chipmunkmod.modules;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
public class Chat {
public static final ThreadLocal<Boolean> NEXT_CHAT_PLAYER = ThreadLocal.withInitial(() -> false);
@ -13,8 +13,8 @@ public class Chat {
if (usePlayerChat) NEXT_CHAT_PLAYER.set(true);
final ClientPlayNetworkHandler networkHandler = MinecraftClient.getInstance().getNetworkHandler();
final ClientPacketListener networkHandler = Minecraft.getInstance().getConnection();
if (networkHandler == null) return;
networkHandler.sendChatMessage(message);
networkHandler.sendChat(message);
}
}

View file

@ -6,11 +6,9 @@ import land.chipmunk.chipmunkmod.listeners.ListenerManager;
import land.chipmunk.chipmunkmod.util.UUIDUtilities;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableTextContent;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.network.chat.contents.TranslatableContents;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@ -19,9 +17,9 @@ public class ChomeNSBotCommandSuggestions implements Listener {
public static final String BOT_SELECTOR_ID = "chomens_bot_selector";
public static final String REQUEST_SUGGESTIONS_ID = "chomens_bot_request_command_suggestion";
public static ChomeNSBotCommandSuggestions INSTANCE = new ChomeNSBotCommandSuggestions(MinecraftClient.getInstance());
public static ChomeNSBotCommandSuggestions INSTANCE = new ChomeNSBotCommandSuggestions(Minecraft.getInstance());
private final MinecraftClient client;
private final Minecraft client;
public boolean receivedSuggestions = false; // can be set through eval
@ -29,7 +27,7 @@ public class ChomeNSBotCommandSuggestions implements Listener {
public List<ChomeNSBotCommand> commands = new ArrayList<>();
public ChomeNSBotCommandSuggestions (final MinecraftClient client) {
public ChomeNSBotCommandSuggestions (final Minecraft client) {
this.client = client;
ListenerManager.addListener(this);
@ -43,11 +41,11 @@ public class ChomeNSBotCommandSuggestions implements Listener {
}
public void forceRequest () {
final ClientPlayerEntity player = client.player;
final LocalPlayer player = client.player;
if (botSelector == null || player == null) return;
final String selector = UUIDUtilities.selector(player.getUuid());
final String selector = UUIDUtilities.selector(player.getUUID());
final Component component = Component
.text(REQUEST_SUGGESTIONS_ID)
@ -67,9 +65,9 @@ public class ChomeNSBotCommandSuggestions implements Listener {
}
@Override
public void overlayMessageReceived (final Text message) {
public void overlayMessageReceived (final net.minecraft.network.chat.Component message) {
if (
!(message.getContent() instanceof final TranslatableTextContent translatableTextContent)
!(message.getContents() instanceof final TranslatableContents translatableTextContent)
|| !translatableTextContent.getKey().isEmpty()
|| translatableTextContent.getArgs().length != 2
|| !(translatableTextContent.getArgs()[0] instanceof final String id)
@ -81,11 +79,11 @@ public class ChomeNSBotCommandSuggestions implements Listener {
}
@Override
public void chatMessageReceived (final Text message) {
final List<Text> children = message.getSiblings();
public void chatMessageReceived (final net.minecraft.network.chat.Component message) {
final List<net.minecraft.network.chat.Component> children = message.getSiblings();
if (children.isEmpty()) return;
final Text textComponent = children.getFirst();
final net.minecraft.network.chat.Component textComponent = children.getFirst();
if (!textComponent.getString().equals(REQUEST_SUGGESTIONS_ID)) return;
commands = children.stream()

View file

@ -4,43 +4,50 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap;
import land.chipmunk.chipmunkmod.ChipmunkMod;
import land.chipmunk.chipmunkmod.listeners.Listener;
import land.chipmunk.chipmunkmod.listeners.ListenerManager;
import land.chipmunk.chipmunkmod.mixin.ClientWorldAccessor;
import land.chipmunk.chipmunkmod.mixin.ClientLevelAccessor;
import land.chipmunk.chipmunkmod.mixin.DebugChartAccessor;
import land.chipmunk.chipmunkmod.mixin.DebugHudAccessor;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.CommandBlock;
import net.minecraft.block.FallingBlock;
import net.minecraft.block.entity.BlockEntityType;
import net.minecraft.block.entity.CommandBlockBlockEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.hud.debug.chart.PingChart;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.network.ClientPlayerInteractionManager;
import net.minecraft.client.network.PendingUpdateManager;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.component.ComponentMap;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.NbtComponent;
import net.minecraft.entity.TypedEntityData;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.ClientConnection;
import net.minecraft.network.packet.c2s.play.*;
import net.minecraft.registry.Registries;
import net.minecraft.registry.tag.BlockTags;
import net.minecraft.state.property.Property;
import net.minecraft.util.Hand;
import net.minecraft.util.Pair;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.debugchart.PingDebugChart;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.multiplayer.MultiPlayerGameMode;
import net.minecraft.client.multiplayer.prediction.BlockStatePredictionHandler;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Vec3i;
import net.minecraft.core.component.DataComponentMap;
import net.minecraft.core.component.DataComponents;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.Connection;
import net.minecraft.network.protocol.game.*;
import net.minecraft.tags.BlockTags;
import net.minecraft.util.Tuple;
import net.minecraft.util.Util;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.*;
import net.minecraft.util.profiler.log.MultiValueDebugSampleLog;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.dimension.DimensionType;
import net.minecraft.util.debugchart.SampleStorage;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.component.CustomData;
import net.minecraft.world.item.component.TypedEntityData;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.CommandBlock;
import net.minecraft.world.level.block.FallingBlock;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.entity.CommandBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.Property;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.util.Collections;
import java.util.Map;
import java.util.Timer;
@ -48,14 +55,14 @@ import java.util.TimerTask;
import java.util.concurrent.CompletableFuture;
public class CommandCore implements Listener {
public static final CommandCore INSTANCE = new CommandCore(MinecraftClient.getInstance());
public static final CommandCore INSTANCE = new CommandCore(Minecraft.getInstance());
private final MinecraftClient client;
private final Minecraft client;
public boolean ready = false;
public BlockPos origin;
public BlockBox noPos;
public BlockBox withPos;
public BoundingBox noPos;
public BoundingBox withPos;
public BlockPos block;
public boolean runFillCommand = true;
public boolean isSingleBlock = false;
@ -67,7 +74,7 @@ public class CommandCore implements Listener {
private int refillTriesUsingPlaceBlock = 0;
private DimensionType oldDimension;
public CommandCore (final MinecraftClient client) {
public CommandCore (final Minecraft client) {
this.client = client;
reloadFromConfig();
ListenerManager.addListener(this);
@ -88,11 +95,11 @@ public class CommandCore implements Listener {
if (client.player == null) return;
move(client.player.getEyePos());
move(client.player.getEyePosition());
}
private void tick () {
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
final ClientPacketListener networkHandler = client.getConnection();
if (networkHandler == null) {
cleanup();
@ -104,7 +111,7 @@ public class CommandCore implements Listener {
public void reloadFromConfig () {
noPos = ChipmunkMod.CONFIG.core.relativeArea;
isSingleBlock = noPos.getDimensions().equals(Vec3i.ZERO);
isSingleBlock = noPos.getLength().equals(Vec3i.ZERO);
}
@Override
@ -149,23 +156,23 @@ public class CommandCore implements Listener {
public void check () {
if (isSingleBlock) return;
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
final ClientPacketListener networkHandler = client.getConnection();
if (networkHandler == null || withPos == null || !ready) return;
final ClientPlayerEntity player = client.player;
final ClientWorld world = client.world;
final LocalPlayer player = client.player;
final ClientLevel world = client.level;
if (player == null || world == null) return;
if (oldDimension != null && !oldDimension.equals(world.getDimension())) move(client.player.getEyePos());
if (oldDimension != null && !oldDimension.equals(world.dimensionType())) move(client.player.getEyePosition());
oldDimension = world.getDimension();
oldDimension = world.dimensionType();
try {
for (int x = withPos.getMinX(); x <= withPos.getMaxX(); x++) {
for (int y = withPos.getMinY(); y <= withPos.getMaxY(); y++) {
for (int z = withPos.getMinZ(); z <= withPos.getMaxZ(); z++) {
for (int x = withPos.minX(); x <= withPos.maxX(); x++) {
for (int y = withPos.minY(); y <= withPos.maxY(); y++) {
for (int z = withPos.minZ(); z <= withPos.maxZ(); z++) {
final BlockPos pos = new BlockPos(x, y, z);
final Block block = world.getBlockState(pos).getBlock();
@ -183,29 +190,29 @@ public class CommandCore implements Listener {
}
}
public void move (final Vec3d position) {
final ClientWorld world = client.world;
public void move (final Vec3 position) {
final ClientLevel world = client.level;
if (world == null || noPos == null) return;
final DimensionType dimension = world.getDimension();
final DimensionType dimension = world.dimensionType();
final int dimMinY = dimension.minY();
final int dimMaxY = dimension.height() + dimMinY - 1; // -1 accounts for block at Y=0
int yOffset = 0;
if (noPos.getMinY() < dimMinY) {
yOffset = dimMinY - noPos.getMinY();
} else if (noPos.getMaxY() > dimMaxY) {
yOffset = dimMaxY - noPos.getMaxY();
if (noPos.minY() < dimMinY) {
yOffset = dimMinY - noPos.minY();
} else if (noPos.maxY() > dimMaxY) {
yOffset = dimMaxY - noPos.maxY();
}
origin = new BlockPos(
((int) position.getX() / 16) * 16,
noPos.getMinY() + yOffset,
((int) position.getZ() / 16) * 16
((int) position.x() / 16) * 16,
noPos.minY() + yOffset,
((int) position.z() / 16) * 16
);
withPos = noPos.offset(origin.getX(), yOffset, origin.getZ());
block = new BlockPos(withPos.getMinX(), withPos.getMinY(), withPos.getMinZ());
withPos = noPos.moved(origin.getX(), yOffset, origin.getZ());
block = new BlockPos(withPos.minX(), withPos.minY(), withPos.minZ());
refill();
final Timer timer = new Timer();
@ -226,37 +233,33 @@ public class CommandCore implements Listener {
}
public void refill () {
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
final ClientPlayerEntity player = client.player;
final ClientPacketListener networkHandler = client.getConnection();
final LocalPlayer player = client.player;
if (
!runFillCommand || isSingleBlock
|| player == null
|| !player.isInCreativeMode()
|| !player.isCreativeLevelTwoOp()
|| client.world == null
|| !player.hasInfiniteMaterials()
|| !player.canUseGameMasterBlocks()
|| client.level == null
|| networkHandler == null
|| withPos == null
) return;
final Chunk chunk = client.world.getChunk(withPos.getCenter());
if (chunk == null) return;
final String command = String.format(
"fill %s %s %s %s %s %s command_block",
withPos.getMinX(),
withPos.getMinY(),
withPos.getMinZ(),
withPos.minX(),
withPos.minY(),
withPos.minZ(),
withPos.getMaxX(),
withPos.getMaxY(),
withPos.getMaxZ()
withPos.maxX(),
withPos.maxY(),
withPos.maxZ()
);
if (refillTriesUsingPlaceBlock > 5) {
networkHandler.sendChatCommand(command);
networkHandler.sendCommand(command);
refillTriesUsingPlaceBlock = 0;
} else {
runPlaceBlock(command, true, true);
@ -271,14 +274,14 @@ public class CommandCore implements Listener {
int y = block.getY();
int z = block.getZ();
if (x > withPos.getMaxX()) {
x = withPos.getMinX();
if (x > withPos.maxX()) {
x = withPos.minX();
z++;
if (z > withPos.getMaxZ()) {
z = withPos.getMinZ();
if (z > withPos.maxZ()) {
z = withPos.minZ();
y++;
if (y > withPos.getMaxY()) {
y = withPos.getMinY();
if (y > withPos.maxY()) {
y = withPos.minY();
}
}
}
@ -294,10 +297,10 @@ public class CommandCore implements Listener {
return;
}
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
final ClientPacketListener networkHandler = client.getConnection();
if (networkHandler == null) return;
final ClientConnection connection = networkHandler.getConnection();
final Connection connection = networkHandler.getConnection();
if (block == null) return;
@ -305,10 +308,10 @@ public class CommandCore implements Listener {
if (KaboomCheck.INSTANCE.isKaboom) {
connection.send(
new UpdateCommandBlockC2SPacket(
new ServerboundSetCommandBlockPacket(
block,
command,
CommandBlockBlockEntity.Type.AUTO,
CommandBlockEntity.Mode.AUTO,
false,
false,
true
@ -316,10 +319,10 @@ public class CommandCore implements Listener {
);
} else {
connection.send(
new UpdateCommandBlockC2SPacket(
new ServerboundSetCommandBlockPacket(
block,
"",
CommandBlockBlockEntity.Type.REDSTONE,
CommandBlockEntity.Mode.REDSTONE,
false,
false,
false
@ -327,10 +330,10 @@ public class CommandCore implements Listener {
);
connection.send(
new UpdateCommandBlockC2SPacket(
new ServerboundSetCommandBlockPacket(
block,
command,
CommandBlockBlockEntity.Type.REDSTONE,
CommandBlockEntity.Mode.REDSTONE,
false,
false,
true
@ -341,12 +344,12 @@ public class CommandCore implements Listener {
incrementCurrentBlock();
}
public CompletableFuture<NbtCompound> runTracked (final String command) {
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
public CompletableFuture<CompoundTag> runTracked (final String command) {
final ClientPacketListener networkHandler = client.getConnection();
if (networkHandler == null) return CompletableFuture.completedFuture(null);
final ClientConnection connection = networkHandler.getConnection();
final Connection connection = networkHandler.getConnection();
if (block == null) return CompletableFuture.completedFuture(null);
@ -356,10 +359,10 @@ public class CommandCore implements Listener {
oldBlock = runPlaceBlock(command, false, false);
} else if (KaboomCheck.INSTANCE.isKaboom) {
connection.send(
new UpdateCommandBlockC2SPacket(
new ServerboundSetCommandBlockPacket(
block,
command,
CommandBlockBlockEntity.Type.AUTO,
CommandBlockEntity.Mode.AUTO,
true,
false,
true
@ -369,10 +372,10 @@ public class CommandCore implements Listener {
oldBlock = block;
} else {
connection.send(
new UpdateCommandBlockC2SPacket(
new ServerboundSetCommandBlockPacket(
block,
"",
CommandBlockBlockEntity.Type.REDSTONE,
CommandBlockEntity.Mode.REDSTONE,
true,
false,
false
@ -380,10 +383,10 @@ public class CommandCore implements Listener {
);
connection.send(
new UpdateCommandBlockC2SPacket(
new ServerboundSetCommandBlockPacket(
block,
command,
CommandBlockBlockEntity.Type.REDSTONE,
CommandBlockEntity.Mode.REDSTONE,
true,
false,
true
@ -395,16 +398,16 @@ public class CommandCore implements Listener {
if (oldBlock == null) return CompletableFuture.completedFuture(null);
final CompletableFuture<NbtCompound> future = new CompletableFuture<>();
final CompletableFuture<CompoundTag> future = new CompletableFuture<>();
final Timer timer = new Timer();
final TimerTask queryTask = new TimerTask() {
public void run () {
client.getNetworkHandler().getDataQueryHandler().queryBlockNbt(oldBlock, result -> {
client.getConnection().getDebugQueryHandler().queryBlockEntityTag(oldBlock, result -> {
future.complete(result);
if (isSingleBlock && client.interactionManager != null) {
client.interactionManager.breakBlock(oldBlock);
if (isSingleBlock && client.gameMode != null) {
client.gameMode.destroyBlock(oldBlock);
}
});
}
@ -418,95 +421,95 @@ public class CommandCore implements Listener {
}
public BlockPos runPlaceBlock (final String command, final boolean fallbackToChat, final boolean replaceOldBlock) {
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
final ClientPacketListener networkHandler = client.getConnection();
if (networkHandler == null) return null;
final ClientConnection connection = networkHandler.getConnection();
final Connection connection = networkHandler.getConnection();
final ClientPlayerEntity player = client.player;
final ClientWorld world = client.world;
final LocalPlayer player = client.player;
final ClientLevel world = client.level;
if (player == null || world == null || !player.isInCreativeMode()) return null;
if (player == null || world == null || !player.hasInfiniteMaterials()) return null;
final DimensionType dimensionType = world.getDimension();
final DimensionType dimensionType = world.dimensionType();
final ClientPlayerInteractionManager interactionManager = client.interactionManager;
final MultiPlayerGameMode interactionManager = client.gameMode;
if (interactionManager == null) return null;
// stolen from two five hundred million dollars
final Pair<BlockPos, BlockState> pair = findBlockLocation();
final Tuple<@NotNull BlockPos, @NotNull BlockState> pair = findBlockLocation();
if (
pair == null
|| pair.getLeft().getY() < dimensionType.minY()
|| pair.getLeft().getY() > dimensionType.height() + dimensionType.minY()
|| pair.getA().getY() < dimensionType.minY()
|| pair.getA().getY() > dimensionType.height() + dimensionType.minY()
) {
if (fallbackToChat) networkHandler.sendChatCommand(command);
if (fallbackToChat) networkHandler.sendCommand(command);
return null;
}
final BlockPos position = pair.getLeft();
final BlockState oldBlockState = pair.getRight();
final BlockPos position = pair.getA();
final BlockState oldBlockState = pair.getB();
final int freeHotBarSlot = player.getInventory().getEmptySlot();
final int freeHotBarSlot = player.getInventory().getFreeSlot();
if (freeHotBarSlot == -1 || freeHotBarSlot > 8) {
if (fallbackToChat) networkHandler.sendChatCommand(command);
if (fallbackToChat) networkHandler.sendCommand(command);
return null;
}
final int slot = 36 + freeHotBarSlot;
final int oldSelectedSlot = player.getInventory().getSelectedSlot();
final ItemStack oldStack = player.getInventory().getStack(slot).copy();
final ItemStack oldStack = player.getInventory().getItem(slot).copy();
final ItemStack commandBlock = new ItemStack(Items.COMMAND_BLOCK);
final NbtCompound data = new NbtCompound();
final CompoundTag data = new CompoundTag();
data.putString("Command", command);
data.putBoolean("auto", true);
final NbtCompound blockEntityTag = new NbtCompound();
final CompoundTag blockEntityTag = new CompoundTag();
blockEntityTag.put("BlockEntityTag", data);
commandBlock.applyComponentsFrom(
ComponentMap.builder()
.add(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(blockEntityTag))
.add(DataComponentTypes.BLOCK_ENTITY_DATA, TypedEntityData.create(BlockEntityType.COMMAND_BLOCK, data))
commandBlock.applyComponents(
DataComponentMap.builder()
.set(DataComponents.CUSTOM_DATA, CustomData.of(blockEntityTag))
.set(DataComponents.BLOCK_ENTITY_DATA, TypedEntityData.of(BlockEntityType.COMMAND_BLOCK, data))
.build()
);
connection.send(new CreativeInventoryActionC2SPacket(slot, commandBlock));
connection.send(new ServerboundSetCreativeModeSlotPacket(slot, commandBlock));
if (oldSelectedSlot != freeHotBarSlot) {
connection.send(new UpdateSelectedSlotC2SPacket(freeHotBarSlot));
connection.send(new ServerboundSetCarriedItemPacket(freeHotBarSlot));
}
try (final PendingUpdateManager pendingUpdateManager = ((ClientWorldAccessor) world).getPendingUpdateManager()) {
try (final BlockStatePredictionHandler pendingUpdateManager = ((ClientLevelAccessor) world).getBlockStatePredictionHandler()) {
connection.send(
new PlayerActionC2SPacket(
PlayerActionC2SPacket.Action.START_DESTROY_BLOCK,
new ServerboundPlayerActionPacket(
ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK,
position,
Direction.UP,
pendingUpdateManager.incrementSequence().getSequence()
pendingUpdateManager.startPredicting().currentSequence()
)
);
connection.send(
new PlayerInteractBlockC2SPacket(
Hand.MAIN_HAND,
BlockHitResult.createMissed(
new Vec3d(position),
new ServerboundUseItemOnPacket(
InteractionHand.MAIN_HAND,
BlockHitResult.miss(
new Vec3(position),
Direction.UP,
position
),
pendingUpdateManager.incrementSequence().getSequence()
pendingUpdateManager.startPredicting().currentSequence()
)
);
}
if (oldSelectedSlot != freeHotBarSlot) {
connection.send(new UpdateSelectedSlotC2SPacket(oldSelectedSlot));
connection.send(new ServerboundSetCarriedItemPacket(oldSelectedSlot));
}
connection.send(new CreativeInventoryActionC2SPacket(slot, oldStack));
connection.send(new ServerboundSetCreativeModeSlotPacket(slot, oldStack));
if (ChipmunkMod.CONFIG.core.logCommands)
ChipmunkMod.LOGGER.info("Executing place block core command: {}", command);
@ -519,27 +522,27 @@ public class CommandCore implements Listener {
@Override
public void run () {
// we're gonna just only break the block for now
try (final PendingUpdateManager pendingUpdateManager = ((ClientWorldAccessor) world).getPendingUpdateManager()) {
try (final BlockStatePredictionHandler pendingUpdateManager = ((ClientLevelAccessor) world).getBlockStatePredictionHandler()) {
connection.send(
new PlayerActionC2SPacket(
PlayerActionC2SPacket.Action.START_DESTROY_BLOCK,
new ServerboundPlayerActionPacket(
ServerboundPlayerActionPacket.Action.START_DESTROY_BLOCK,
position,
Direction.UP,
pendingUpdateManager.incrementSequence().getSequence()
pendingUpdateManager.startPredicting().currentSequence()
)
);
}
}
}, 50 + getNextTickWaitTime());
} else {
final StringBuilder oldBlockString = new StringBuilder(Registries.BLOCK.getId(oldBlockState.getBlock()).toString());
final StringBuilder oldBlockString = new StringBuilder(BuiltInRegistries.BLOCK.getKey(oldBlockState.getBlock()).toString());
if (!oldBlockState.getProperties().isEmpty()) {
oldBlockString.append('[');
for (final Property<?> property : oldBlockState.getProperties()) {
oldBlockString.append(property.getName())
.append('=')
.append(Util.getValueAsString(property, property.getValues().getLast())) // water[level=15] instead of water[level=0,level=1,....,level=15]
.append(Util.getPropertyName(property, property.getPossibleValues().getLast())) // water[level=15] instead of water[level=0,level=1,....,level=15]
.append(',');
}
@ -555,33 +558,36 @@ public class CommandCore implements Listener {
}
// also from two five hundred million dollars
private Pair<BlockPos, BlockState> findBlockLocation () {
final ClientPlayerEntity player = client.player;
private Tuple<@NotNull BlockPos, @NotNull BlockState> findBlockLocation () {
final LocalPlayer player = client.player;
if (player == null) return null;
final BlockPos position = player.getBlockPos();
final Box boundingBox = player.getBoundingBox();
boundingBox.expand(1.0);
final BlockPos position = player.blockPosition();
final AABB boundingBox = player.getBoundingBox();
boundingBox.inflate(1.0);
for (int x = position.getX() - 2; x <= position.getX() + 2; x++) {
for (int y = position.getY() - 2; y <= position.getY() + 2; y++) {
for (int z = position.getZ() - 2; z <= position.getZ() + 2; z++) {
final BlockPos blockPos = new BlockPos(x, y, z);
if (!player.canInteractWithBlockAt(blockPos, 1.0)) continue;
if (!player.isWithinBlockInteractionRange(blockPos, 1.0)) continue;
// we don't want to place a block inside ourselves
if (boundingBox.intersects(new Vec3d(blockPos), new Vec3d(blockPos))) continue;
final BlockState blockState = player.getEntityWorld().getBlockState(blockPos);
if (blockState.getBlock() instanceof FallingBlock || blockState.getBlock() instanceof CommandBlock)
continue;
final boolean replaceable = blockState.isIn(BlockTags.REPLACEABLE);
if (
!replaceable
&& !blockState.isIn(BlockTags.AXE_MINEABLE)
&& !blockState.isIn(BlockTags.HOE_MINEABLE)
&& !blockState.isIn(BlockTags.SHOVEL_MINEABLE)
&& !blockState.isIn(BlockTags.PICKAXE_MINEABLE)
) {
continue;
}
return new Pair<>(blockPos, blockState);
if (boundingBox.intersects(new Vec3(blockPos), new Vec3(blockPos))) continue;
try (final Level level = player.level()) {
final BlockState blockState = level.getBlockState(blockPos);
if (blockState.getBlock() instanceof FallingBlock
|| blockState.getBlock() instanceof CommandBlock)
continue;
final boolean replaceable = blockState.is(BlockTags.REPLACEABLE);
if (
!replaceable
&& !blockState.is(BlockTags.MINEABLE_WITH_AXE)
&& !blockState.is(BlockTags.MINEABLE_WITH_HOE)
&& !blockState.is(BlockTags.MINEABLE_WITH_SHOVEL)
&& !blockState.is(BlockTags.MINEABLE_WITH_PICKAXE)
) {
continue;
}
return new Tuple<>(blockPos, blockState);
} catch (final IOException ignored) { }
}
}
}
@ -590,16 +596,16 @@ public class CommandCore implements Listener {
}
private int getNextTickWaitTime () {
final PingChart pingChart = ((DebugHudAccessor) client.getDebugHud()).getPingChart();
final MultiValueDebugSampleLog log = ((DebugChartAccessor) pingChart).getLog();
final PingDebugChart pingChart = ((DebugHudAccessor) client.getDebugOverlay()).getPingChart();
final SampleStorage log = ((DebugChartAccessor) pingChart).getSampleStorage();
long sum = 0L;
for (int i = 0; i < log.getLength(); ++i) {
for (int i = 0; i < log.size(); ++i) {
sum += log.get(0);
}
return Math.min(Math.round((float) sum / log.getLength()), 5 * 1000);
return Math.min(Math.round((float) sum / log.size()), 5 * 1000);
}
public void cleanup () {

View file

@ -1,24 +1,24 @@
package land.chipmunk.chipmunkmod.modules;
import com.mojang.brigadier.CommandDispatcher;
import net.minecraft.client.MinecraftClient;
import net.minecraft.command.CommandSource;
import net.minecraft.command.DefaultPermissions;
import net.minecraft.client.Minecraft;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.server.permissions.Permissions;
public class KaboomCheck {
public static final KaboomCheck INSTANCE = new KaboomCheck();
private static final String CHECKED_COMMAND_OP = "extras:prefix"; // Added circa 2018
private static final String CHECKED_COMMAND = "minecraft:op"; // It'd be a bit weird for non-Kaboom servers to allow /op without OP...
private final MinecraftClient client = MinecraftClient.getInstance();
private final Minecraft client = Minecraft.getInstance();
public boolean isKaboom = false;
public void onJoin () {
this.isKaboom = false;
}
public void onCommandTree (final CommandDispatcher<CommandSource> dispatcher) {
public void onCommandTree (final CommandDispatcher<SharedSuggestionProvider> dispatcher) {
assert client.player != null; // We can only receive this packet while in a server
final String checkedCommand = client.player.getPermissions().hasPermission(DefaultPermissions.OWNERS)
final String checkedCommand = client.player.permissions().hasPermission(Permissions.COMMANDS_OWNER)
? CHECKED_COMMAND_OP : CHECKED_COMMAND;
this.isKaboom = dispatcher.getRoot().getChild(checkedCommand) != null;

View file

@ -8,16 +8,15 @@ import land.chipmunk.chipmunkmod.util.UUIDUtilities;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
public class RainbowName {
public static final RainbowName INSTANCE = new RainbowName(MinecraftClient.getInstance());
private final MinecraftClient client;
public static final RainbowName INSTANCE = new RainbowName(Minecraft.getInstance());
private final Minecraft client;
private final Random random = new Random();
public boolean enabled = false;
@ -26,9 +25,9 @@ public class RainbowName {
private String team;
private int startHue = 0;
public RainbowName (final MinecraftClient client) {
public RainbowName (final Minecraft client) {
this.client = client;
this.displayName = client.getSession().getUsername();
this.displayName = client.getUser().getName();
}
public void init () {
@ -45,15 +44,15 @@ public class RainbowName {
}
public void enable () {
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
final ClientPacketListener networkHandler = client.getConnection();
if (networkHandler == null) return;
final GameProfile profile = networkHandler.getProfile();
final GameProfile profile = networkHandler.getLocalGameProfile();
final String username = RandomUtilities.emptyUsername(random);
team = RandomUtilities.randomString(random, RandomUtilities.TEAM_ALLOWED_CHARS, 16);
final String selfSelector = UUIDUtilities.selector(profile.id());
networkHandler.sendChatCommand("extras:username " + username);
networkHandler.sendCommand("extras:username " + username);
CommandCore.INSTANCE.run("minecraft:team add " + team);
CommandCore.INSTANCE.run("minecraft:team join " + team + " " + selfSelector);
@ -61,22 +60,22 @@ public class RainbowName {
}
public void disable () {
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
final ClientPacketListener networkHandler = client.getConnection();
if (networkHandler == null) {
enabled = false;
return;
}
final GameProfile profile = networkHandler.getProfile();
final GameProfile profile = networkHandler.getLocalGameProfile();
CommandCore.INSTANCE.run("essentials:nick " + profile.id() + " off");
CommandCore.INSTANCE.run("minecraft:team remove " + team);
networkHandler.sendChatCommand("extras:username " + profile.name());
networkHandler.sendCommand("extras:username " + profile.name());
enabled = false;
}
private void tick () {
try {
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
final ClientPacketListener networkHandler = client.getConnection();
if (networkHandler == null) {
cleanup();
@ -85,7 +84,7 @@ public class RainbowName {
if (!enabled) return;
final GameProfile profile = networkHandler.getProfile();
final GameProfile profile = networkHandler.getLocalGameProfile();
int hue = startHue;
final int increment = (int) (360.0 / Math.max(displayName.length(), 20));

View file

@ -3,34 +3,34 @@ package land.chipmunk.chipmunkmod.modules;
import land.chipmunk.chipmunkmod.ChipmunkMod;
import land.chipmunk.chipmunkmod.listeners.Listener;
import land.chipmunk.chipmunkmod.listeners.ListenerManager;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.command.DefaultPermissions;
import net.minecraft.network.packet.Packet;
import net.minecraft.network.packet.c2s.play.ChangeGameModeC2SPacket;
import net.minecraft.text.Text;
import net.minecraft.world.GameMode;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ServerboundChangeGameModePacket;
import net.minecraft.server.permissions.Permissions;
import net.minecraft.world.level.GameType;
import static land.chipmunk.chipmunkmod.util.ServerUtilities.serverHasCommand;
public class SelfCare implements Listener {
public static final SelfCare INSTANCE = new SelfCare(MinecraftClient.getInstance());
public static final SelfCare INSTANCE = new SelfCare(Minecraft.getInstance());
private final MinecraftClient client;
private final Minecraft client;
public boolean configOpEnabled = ChipmunkMod.CONFIG.selfCare.op;
public boolean configGameModeEnabled = ChipmunkMod.CONFIG.selfCare.gameMode;
public boolean configCommandSpyEnabled = ChipmunkMod.CONFIG.selfCare.cspy;
public GameMode targetGameMode = GameMode.CREATIVE;
public GameType targetGameMode = GameType.CREATIVE;
public String targetSkin;
public boolean hasSkin = false;
private boolean isCommandSpyEnabled = false;
public SelfCare (final MinecraftClient client) {
public SelfCare (final Minecraft client) {
this.client = client;
this.targetSkin = ChipmunkMod.CONFIG.autoSkinUsername == null ? "off" : ChipmunkMod.CONFIG.autoSkinUsername;
@ -47,7 +47,7 @@ public class SelfCare implements Listener {
}
@Override
public void chatMessageReceived (final Text message) {
public void chatMessageReceived (final Component message) {
final String stringMessage = message.getString();
if (stringMessage.equals("Successfully enabled CommandSpy")) isCommandSpyEnabled = true;
@ -62,38 +62,38 @@ public class SelfCare implements Listener {
@Override
public void timeUpdate () {
final ClientPlayerEntity player = client.player;
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
final LocalPlayer player = client.player;
final ClientPacketListener networkHandler = client.getConnection();
if (networkHandler == null || player == null) return;
if (
!player.getPermissions().hasPermission(DefaultPermissions.OWNERS)
!player.permissions().hasPermission(Permissions.COMMANDS_OWNER)
&& configOpEnabled
&& serverHasCommand("op")
) {
networkHandler.sendChatCommand("op @s[type=player]");
} else if (player.getGameMode() != targetGameMode && configGameModeEnabled) {
networkHandler.sendCommand("op @s[type=player]");
} else if (player.gameMode() != targetGameMode && configGameModeEnabled) {
// ViaVersion will automatically convert this to `/gamemode creative`
networkHandler.sendPacket(new ChangeGameModeC2SPacket(targetGameMode));
networkHandler.send(new ServerboundChangeGameModePacket(targetGameMode));
} else if (!isCommandSpyEnabled && configCommandSpyEnabled && serverHasCommand("c")) {
if (
!CommandCore.INSTANCE.ready
|| !CommandCore.INSTANCE.runFillCommand
|| !player.isCreativeLevelTwoOp()
|| !player.canUseGameMasterBlocks()
) {
networkHandler.sendChatCommand("c on");
networkHandler.sendCommand("c on");
} else {
CommandCore.INSTANCE.run("c " + player.getUuidAsString() + " on");
CommandCore.INSTANCE.run("c " + player.getStringUUID() + " on");
}
} else if (!hasSkin && !targetSkin.equalsIgnoreCase("off")) {
networkHandler.sendChatCommand("skin " + targetSkin);
networkHandler.sendCommand("skin " + targetSkin);
}
}
@Override
public void packetSent (final Packet<?> packet) {
if (packet instanceof ChangeGameModeC2SPacket (final GameMode mode)) {
if (packet instanceof ServerboundChangeGameModePacket (final GameType mode)) {
targetGameMode = mode;
}
}

View file

@ -9,14 +9,12 @@ import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvent;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.resources.Identifier;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundSource;
import java.io.File;
import java.net.URL;
import java.nio.file.Path;
@ -26,7 +24,7 @@ import java.util.TimerTask;
public class SongPlayer {
public static final String SELECTOR = "@a[tag=!nomusic,tag=!chipmunkmod_nomusic]";
public static final SongPlayer INSTANCE = new SongPlayer(MinecraftClient.getInstance());
public static final SongPlayer INSTANCE = new SongPlayer(Minecraft.getInstance());
public static File SONG_DIR = new File("songs");
static {
@ -35,7 +33,7 @@ public class SongPlayer {
}
}
private final MinecraftClient client;
private final Minecraft client;
public Song currentSong;
public LinkedList<Song> songQueue = new LinkedList<>();
public Timer playTimer;
@ -46,7 +44,7 @@ public class SongPlayer {
public float pitch = 0;
private int ticksUntilPausedActionbar = 20;
public SongPlayer (final MinecraftClient client) {
public SongPlayer (final Minecraft client) {
this.client = client;
}
@ -54,7 +52,7 @@ public class SongPlayer {
// TODO: Reduce the mess
public void loadSong (final Path location) {
final ClientPlayerEntity player = client.player;
final LocalPlayer player = client.player;
if (player == null) return;
@ -75,7 +73,7 @@ public class SongPlayer {
}
public void loadSong (final URL location) {
final ClientPlayerEntity player = client.player;
final LocalPlayer player = client.player;
if (player == null) return;
@ -101,7 +99,7 @@ public class SongPlayer {
final TimerTask playTask = new TimerTask() {
@Override
public void run () {
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
final ClientPacketListener networkHandler = client.getConnection();
if (networkHandler == null) {
disconnected();
@ -110,7 +108,7 @@ public class SongPlayer {
if (loaderThread != null && !loaderThread.isAlive() && client.player != null) {
if (loaderThread.exception != null) {
final Text exceptionMessage = loaderThread.exception.message;
final net.minecraft.network.chat.Component exceptionMessage = loaderThread.exception.message;
client.execute(() -> client.player.sendMessage(Component.translatable("Failed to load song: %s", Component.text(exceptionMessage.getString())).color(NamedTextColor.RED)));
} else {
songQueue.add(loaderThread.song);
@ -169,7 +167,7 @@ public class SongPlayer {
}
public Component generateActionbar () {
final ClientPlayerEntity player = client.player;
final LocalPlayer player = client.player;
final Component component = Component.empty()
.append(Component.translatable("%s", player.getName().getString()).color(NamedTextColor.GREEN))
@ -236,12 +234,12 @@ public class SongPlayer {
final String sound = note.instrument.sound;
client.submit(() -> client.world.playSoundClient(
client.player.getX() + note.position.getX(),
client.player.getY() + note.position.getY(),
client.player.getZ() + note.position.getZ(),
SoundEvent.of(Identifier.of(Key.MINECRAFT_NAMESPACE, sound)),
SoundCategory.RECORDS,
client.submit(() -> client.level.playLocalSound(
client.player.getX() + note.position.x(),
client.player.getY() + note.position.y(),
client.player.getZ() + note.position.z(),
SoundEvent.createVariableRangeEvent(Identifier.fromNamespaceAndPath(Key.MINECRAFT_NAMESPACE, sound)),
SoundSource.RECORDS,
note.volume,
floatingPitch,
true
@ -257,9 +255,9 @@ public class SongPlayer {
note.instrument.sound,
note.position.getX(),
note.position.getY(),
note.position.getZ(),
note.position.x(),
note.position.y(),
note.position.z(),
note.volume,
floatingPitch

View file

@ -11,15 +11,14 @@ import net.kyori.adventure.text.format.Style;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.util.StringHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.util.StringUtil;
import java.util.Map;
import java.util.regex.Pattern;
public class CustomChat {
public static final CustomChat INSTANCE = new CustomChat(MinecraftClient.getInstance());
public static final CustomChat INSTANCE = new CustomChat(Minecraft.getInstance());
private static final GsonComponentSerializer GSON = GsonComponentSerializer.gson();
private static final CustomChatComponentRenderer RENDERER = new CustomChatComponentRenderer();
@ -54,14 +53,14 @@ public class CustomChat {
public static final ThreadLocal<Boolean> SHOULD_IGNORE_INVALID_CHAR = ThreadLocal.withInitial(() -> true);
private final MinecraftClient client;
private final Minecraft client;
public boolean enabled;
public boolean onlyUseWhenNecessary;
public Component format;
public CustomChat (final MinecraftClient client) {
public CustomChat (final Minecraft client) {
this.client = client;
reloadFromConfig();
}
@ -73,7 +72,7 @@ public class CustomChat {
}
public void chat (final String message) {
final ClientPlayerEntity player = client.player;
final LocalPlayer player = client.player;
if (player == null) return;
if (shouldUsePlayerChat(player, message)) {
Chat.sendChatMessage(message, true);
@ -82,9 +81,9 @@ public class CustomChat {
final Component styledMessage = SERIALIZER.deserialize(message);
final String username = MinecraftClient.getInstance().getSession().getUsername();
final String username = Minecraft.getInstance().getUser().getName();
final CustomChatContext context = new CustomChatContext(player.getUuidAsString(), styledMessage,
final CustomChatContext context = new CustomChatContext(player.getStringUUID(), styledMessage,
Map.of("MESSAGE", message, "USERNAME", username));
final Component renderedFormat = RENDERER.render(format, context)
.compact();
@ -93,8 +92,8 @@ public class CustomChat {
CommandCore.INSTANCE.run((KaboomCheck.INSTANCE.isKaboom ? "minecraft:tellraw @a " : "tellraw @a ") + json);
}
private boolean shouldUsePlayerChat (final ClientPlayerEntity player, final String message) {
return !enabled || isUnnecessary(message) || !player.isCreativeLevelTwoOp();
private boolean shouldUsePlayerChat (final LocalPlayer player, final String message) {
return !enabled || isUnnecessary(message) || !player.canUseGameMasterBlocks();
}
private boolean isUnnecessary (final String message) {
@ -102,7 +101,7 @@ public class CustomChat {
for (final char character : message.toCharArray()) {
SHOULD_IGNORE_INVALID_CHAR.set(false);
if (!StringHelper.isValidChar(character)) return false;
if (!StringUtil.isAllowedChatCharacter(character)) return false;
}
return true;

View file

@ -1,8 +1,7 @@
package land.chipmunk.chipmunkmod.song;
import land.chipmunk.chipmunkmod.util.DownloadUtilities;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.phys.Vec3;
import javax.sound.midi.*;
import java.io.ByteArrayInputStream;
import java.io.File;
@ -354,7 +353,7 @@ public class MidiConverter {
final float volume = (float) velocity / 127.0f;
final long time = microTime / 1000L;
return new Note(instrument, pitch, volume, time, Vec3d.ZERO);
return new Note(instrument, pitch, volume, time, Vec3.ZERO);
}
private static Note getMidiPercussionNote (final int midiPitch, final int velocity, final long microTime) {
@ -365,7 +364,7 @@ public class MidiConverter {
final Instrument instrument = Instrument.fromId(noteId / 25);
final long time = microTime / 1000L;
return new Note(instrument, pitch, volume, time, Vec3d.ZERO);
return new Note(instrument, pitch, volume, time, Vec3.ZERO);
}
return null;
}

View file

@ -1,11 +1,10 @@
package land.chipmunk.chipmunkmod.song;
import net.minecraft.util.math.Vec3d;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import net.minecraft.world.phys.Vec3;
public class NBSConverter {
public static Instrument[] instrumentIndex = new Instrument[] {
@ -175,7 +174,7 @@ public class NBSConverter {
else if (value == 100) x = 0;
else x = ((value - 100) * -1) / 100;
final Vec3d position = new Vec3d(x, 0, 0);
final Vec3 position = new Vec3(x, 0, 0);
song.add(new Note(instrument, pitch, (float) note.velocity * (float) layerVolume / 10000f, getMilliTime(note.tick, tempo), position));
}

View file

@ -1,16 +1,16 @@
package land.chipmunk.chipmunkmod.song;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.phys.Vec3;
public class Note implements Comparable<Note> {
public Instrument instrument;
public double pitch;
public float volume;
public long time;
public Vec3d position;
public Vec3 position;
public Note (final Instrument instrument, final double pitch, final float volume, final long time, final Vec3d position) {
public Note (final Instrument instrument, final double pitch, final float volume, final long time, final Vec3 position) {
this.instrument = instrument;
this.pitch = pitch;
this.volume = volume;

View file

@ -1,16 +1,16 @@
package land.chipmunk.chipmunkmod.song;
import net.minecraft.text.Text;
import net.minecraft.network.chat.Component;
public class SongLoaderException extends Exception {
public final Text message;
public final Component message;
public SongLoaderException (final Text message) {
public SongLoaderException (final Component message) {
super();
this.message = message;
}
public SongLoaderException (final Text message, final Throwable cause) {
public SongLoaderException (final Component message, final Throwable cause) {
super(null, cause);
this.message = message;
}

View file

@ -2,8 +2,7 @@ package land.chipmunk.chipmunkmod.song;
import land.chipmunk.chipmunkmod.modules.SongPlayer;
import land.chipmunk.chipmunkmod.util.DownloadUtilities;
import net.minecraft.text.Text;
import net.minecraft.network.chat.Component;
import java.io.File;
import java.net.URL;
import java.nio.file.Files;
@ -40,7 +39,7 @@ public class SongLoaderThread extends Thread {
name = songPath.getName();
}
} catch (final Exception e) {
exception = new SongLoaderException(Text.literal(e.getMessage()), e);
exception = new SongLoaderException(Component.literal(e.getMessage()), e);
return;
}
@ -58,7 +57,7 @@ public class SongLoaderThread extends Thread {
}
if (song == null) {
exception = new SongLoaderException(Text.translatable("Invalid song format"));
exception = new SongLoaderException(Component.translatable("Invalid song format"));
}
}

View file

@ -5,9 +5,9 @@ import land.chipmunk.chipmunkmod.ChipmunkMod;
import land.chipmunk.chipmunkmod.config.Configuration;
import land.chipmunk.chipmunkmod.modules.Chat;
import land.chipmunk.chipmunkmod.modules.custom_chat.CustomChat;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.player.LocalPlayer;
import org.apache.commons.codec.binary.Hex;
import java.math.BigInteger;
@ -19,8 +19,8 @@ import java.util.Arrays;
public class BotValidationUtilities {
public static int hbot (final String command) throws RuntimeException {
final Configuration.BotInfo info = ChipmunkMod.CONFIG.bots.hbot;
final MinecraftClient client = MinecraftClient.getInstance();
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
final Minecraft client = Minecraft.getInstance();
final ClientPacketListener networkHandler = client.getConnection();
final String prefix = info.prefix;
final String key = info.key;
@ -30,7 +30,7 @@ public class BotValidationUtilities {
try {
final MessageDigest md = MessageDigest.getInstance("SHA-256");
final String time = String.valueOf(System.currentTimeMillis() / 10000);
final String input = prefix + command.replaceAll("&[0-9a-fklmnor]", "") + ";" + client.player.getUuidAsString() + ";" + time + ";" + key;
final String input = prefix + command.replaceAll("&[0-9a-fklmnor]", "") + ";" + client.player.getStringUUID() + ";" + time + ";" + key;
final byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8));
final BigInteger bigInt = new BigInteger(1, Arrays.copyOfRange(hash, 0, 4));
final String stringHash = bigInt.toString(Character.MAX_RADIX);
@ -45,8 +45,8 @@ public class BotValidationUtilities {
public static int sbot (final String command) throws RuntimeException {
final Configuration.BotInfo info = ChipmunkMod.CONFIG.bots.sbot;
final MinecraftClient client = MinecraftClient.getInstance();
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
final Minecraft client = Minecraft.getInstance();
final ClientPacketListener networkHandler = client.getConnection();
final String prefix = info.prefix;
final String key = info.key;
@ -72,9 +72,9 @@ public class BotValidationUtilities {
public static int chomens (final String command) throws RuntimeException {
final Configuration.BotInfo info = ChipmunkMod.CONFIG.bots.chomens;
final MinecraftClient client = MinecraftClient.getInstance();
final Minecraft client = Minecraft.getInstance();
final ClientPlayerEntity player = client.player;
final LocalPlayer player = client.player;
final String prefix = info.prefix;
final String key = info.key;
@ -92,11 +92,11 @@ public class BotValidationUtilities {
final MessageDigest md = MessageDigest.getInstance("SHA-256");
final String time = String.valueOf(System.currentTimeMillis() / 5_000);
final String input = player.getUuidAsString() + joinedSplitInput + time + key;
final String input = player.getStringUUID() + joinedSplitInput + time + key;
final byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8));
String stringHash = new String(Hex.encodeHex(hash)).substring(0, 16);
final boolean shouldSectionSign = CustomChat.INSTANCE.enabled && player.isCreativeLevelTwoOp();
final boolean shouldSectionSign = CustomChat.INSTANCE.enabled && player.canUseGameMasterBlocks();
if (shouldSectionSign) {
stringHash = String.join("",
@ -126,7 +126,7 @@ public class BotValidationUtilities {
public static int qilk (final String command) throws RuntimeException {
final Configuration.BotInfo info = ChipmunkMod.CONFIG.bots.qilk;
final MinecraftClient client = MinecraftClient.getInstance();
final Minecraft client = Minecraft.getInstance();
final String prefix = info.prefix;
final String key = info.key;
@ -141,7 +141,7 @@ public class BotValidationUtilities {
final String[] restArguments = Arrays.copyOfRange(wholeArguments, 1, wholeArguments.length);
// lol this is literally chomens bot input with uwu and :
final String input = "uwu:" + key + ":" + client.player.getUuidAsString() + ":" + wholeArguments[0] + ":" + time;
final String input = "uwu:" + key + ":" + client.player.getStringUUID() + ":" + wholeArguments[0] + ":" + time;
final byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8));
final String stringHash = new String(Hex.encodeHex(hash));
@ -189,7 +189,7 @@ public class BotValidationUtilities {
public static int nbot (final String command) throws RuntimeException {
final Configuration.BotInfo info = ChipmunkMod.CONFIG.bots.nbot;
final MinecraftClient client = MinecraftClient.getInstance();
final Minecraft client = Minecraft.getInstance();
final String prefix = info.prefix;
final String key = info.key;
@ -204,7 +204,7 @@ public class BotValidationUtilities {
final long time = Math.floorDiv(System.currentTimeMillis(), 250);
// yep it is very raw code indeed.
final String input = "ThisCodeIsRaw;" + client.player.getUuidAsString() + ";" + time + ";" + key;
final String input = "ThisCodeIsRaw;" + client.player.getStringUUID() + ";" + time + ";" + key;
final byte[] digest = md.digest(input.getBytes(StandardCharsets.UTF_8));
final byte[] positiveDigest = new byte[digest.length + 1];
@ -236,7 +236,7 @@ public class BotValidationUtilities {
public static int kittycorp (final String command) throws RuntimeException {
final Configuration.BotInfo info = ChipmunkMod.CONFIG.bots.kittycorp;
final ClientPlayNetworkHandler networkHandler = MinecraftClient.getInstance().getNetworkHandler();
final ClientPacketListener networkHandler = Minecraft.getInstance().getConnection();
final String prefix = info.prefix;
final String key = info.key;

View file

@ -0,0 +1,14 @@
package land.chipmunk.chipmunkmod.util;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ComponentContents;
import net.minecraft.network.chat.contents.PlainTextContents;
public class ComponentUtilities {
public static String plainOrNull (final Component text) {
final ComponentContents content = text.getContents();
if (!(content instanceof final PlainTextContents plainContent)) return null;
return plainContent.text();
}
}

View file

@ -1,15 +1,15 @@
package land.chipmunk.chipmunkmod.util;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
public class ServerUtilities {
public static boolean serverHasCommand (final String name) {
final MinecraftClient client = MinecraftClient.getInstance();
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
final Minecraft client = Minecraft.getInstance();
final ClientPacketListener networkHandler = client.getConnection();
if (networkHandler == null) return false;
return networkHandler.getCommandDispatcher().getRoot().getChild(name) != null;
return networkHandler.getCommands().getRoot().getChild(name) != null;
}
}

View file

@ -1,12 +0,0 @@
package land.chipmunk.chipmunkmod.util;
import net.minecraft.text.*;
public class TextUtilities {
public static String plainOrNull (final Text text) {
final TextContent content = text.getContent();
if (!(content instanceof final PlainTextContent plainContent)) return null;
return plainContent.string();
}
}

View file

@ -1,15 +1,15 @@
package land.chipmunk.chipmunkmod.util.configurate;
import net.minecraft.util.math.BlockBox;
import net.minecraft.util.math.BlockPos;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import org.spongepowered.configurate.serialize.TypeSerializer;
import java.lang.reflect.Type;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
public class BlockBoxTypeSerializer implements TypeSerializer<BlockBox> {
public class BlockBoxTypeSerializer implements TypeSerializer<BoundingBox> {
public static final BlockBoxTypeSerializer INSTANCE = new BlockBoxTypeSerializer();
private static final String START = "start";
private static final String END = "end";
@ -18,22 +18,22 @@ public class BlockBoxTypeSerializer implements TypeSerializer<BlockBox> {
}
@Override
public BlockBox deserialize (final Type type, final ConfigurationNode source) throws SerializationException {
public BoundingBox deserialize (final Type type, final ConfigurationNode source) throws SerializationException {
final BlockPos start = ConfigurateUtilities.getNodeOrThrow(source, START).require(BlockPos.class);
final BlockPos end = ConfigurateUtilities.getNodeOrThrow(source, END).require(BlockPos.class);
return BlockBox.create(start, end);
return BoundingBox.fromCorners(start, end);
}
@Override
public void serialize (final Type type, final @Nullable BlockBox box,
public void serialize (final Type type, final @Nullable BoundingBox box,
final ConfigurationNode target) throws SerializationException {
if (box == null) {
target.raw(null);
return;
}
target.node(START).set(BlockPos.class, new BlockPos(box.getMinX(), box.getMinY(), box.getMinZ()));
target.node(END).set(BlockPos.class, new BlockPos(box.getMaxX(), box.getMaxY(), box.getMaxZ()));
target.node(START).set(BlockPos.class, new BlockPos(box.minX(), box.minY(), box.minZ()));
target.node(END).set(BlockPos.class, new BlockPos(box.maxX(), box.maxY(), box.maxZ()));
}
}

View file

@ -1,12 +1,12 @@
package land.chipmunk.chipmunkmod.util.configurate;
import net.minecraft.util.math.BlockPos;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.serialize.SerializationException;
import org.spongepowered.configurate.serialize.TypeSerializer;
import java.lang.reflect.Type;
import net.minecraft.core.BlockPos;
public class BlockPosTypeSerializer implements TypeSerializer<BlockPos> {
public static final BlockPosTypeSerializer INSTANCE = new BlockPosTypeSerializer();

View file

@ -2,8 +2,8 @@ package land.chipmunk.chipmunkmod.util.configurate;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.renderer.ComponentRenderer;
import net.minecraft.util.math.BlockBox;
import net.minecraft.util.math.BlockPos;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.levelgen.structure.BoundingBox;
import org.spongepowered.configurate.ConfigurationNode;
import org.spongepowered.configurate.gson.GsonConfigurationLoader;
import org.spongepowered.configurate.serialize.SerializationException;
@ -16,7 +16,7 @@ public final class ConfigurateUtilities {
private static final TypeSerializerCollection CUSTOM_SERIALIZER_COLLECTION = TypeSerializerCollection.builder()
.registerAll(GsonConfigurationLoader.gsonSerializers())
.register(BlockPos.class, BlockPosTypeSerializer.INSTANCE)
.register(BlockBox.class, BlockBoxTypeSerializer.INSTANCE)
.register(BoundingBox.class, BlockBoxTypeSerializer.INSTANCE)
.register(Component.class, ComponentTypeSerializer.INSTANCE)
.build();

View file

@ -4,19 +4,19 @@
"package": "land.chipmunk.chipmunkmod.mixin",
"compatibilityLevel": "JAVA_21",
"client": [
"ChatInputSuggestorMixin",
"CommandSuggestionsMixin",
"ChatScreenMixin",
"ClientCommonNetworkHandlerAccessor",
"ClientConnectionMixin",
"ClientPlayerEntityMixin",
"ClientPlayNetworkHandlerMixin",
"ClientWorldAccessor",
"ClientCommonPacketListenerImplAccessor",
"ConnectionMixin",
"LocalPlayerMixin",
"ClientPacketListenerMixin",
"ClientLevelAccessor",
"DebugChartAccessor",
"DebugHudAccessor",
"MinecraftClientAccessor",
"StringHelperMixin",
"ElderGuardianAppearanceParticleMixin",
"SoundSystemMixin"
"MinecraftAccessor",
"StringUtilMixin",
"ElderGuardianParticleProviderMixin",
"SoundEngineMixin"
],
"injectors": {
"defaultRequire": 1