forked from ChomeNS/chipmunkmod
Merged chomens mod cummits
This commit is contained in:
commit
5a68eb0848
32 changed files with 881 additions and 497 deletions
|
@ -1,9 +1,10 @@
|
||||||
package land.chipmunk.chipmunkmod;
|
package land.chipmunk.chipmunkmod;
|
||||||
|
|
||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import land.chipmunk.chipmunkmod.testclient.modules.utility.AntiChatSpamModule;
|
|
||||||
import land.chipmunk.chipmunkmod.util.Keybinds;
|
import land.chipmunk.chipmunkmod.util.Keybinds;
|
||||||
import land.chipmunk.chipmunkmod.util.TickRunnableHandler;
|
import land.chipmunk.chipmunkmod.util.TickRunnableHandler;
|
||||||
|
import land.chipmunk.chipmunkmod.modules.KaboomCheck;
|
||||||
|
import land.chipmunk.chipmunkmod.modules.Players;
|
||||||
import land.chipmunk.chipmunkmod.util.gson.BlockPosTypeAdapter;
|
import land.chipmunk.chipmunkmod.util.gson.BlockPosTypeAdapter;
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -14,6 +15,8 @@ import java.io.BufferedWriter;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -29,6 +32,8 @@ public class ChipmunkMod implements ModInitializer {
|
||||||
private static File CONFIG_DIR = new File("config");
|
private static File CONFIG_DIR = new File("config");
|
||||||
private static File CONFIG_FILE = new File(CONFIG_DIR, "chipmunkmod.json");
|
private static File CONFIG_FILE = new File(CONFIG_DIR, "chipmunkmod.json");
|
||||||
|
|
||||||
|
public static ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onInitialize () {
|
public void onInitialize () {
|
||||||
// This code runs as soon as Minecraft is in a mod-load-ready state.
|
// This code runs as soon as Minecraft is in a mod-load-ready state.
|
||||||
|
@ -43,6 +48,11 @@ public class ChipmunkMod implements ModInitializer {
|
||||||
Keybinds.registerOpenGui();
|
Keybinds.registerOpenGui();
|
||||||
TickRunnableHandler.registerTickEndRunnables();
|
TickRunnableHandler.registerTickEndRunnables();
|
||||||
LOGGER.info("Loaded ChipmunkMod (Blackilykat's fork)");
|
LOGGER.info("Loaded ChipmunkMod (Blackilykat's fork)");
|
||||||
|
|
||||||
|
Players.INSTANCE.init();
|
||||||
|
KaboomCheck.INSTANCE.init();
|
||||||
|
|
||||||
|
LOGGER.info("Loaded ChipmunkMod (chayapak's fork)");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Configuration loadConfig () throws IOException {
|
public static Configuration loadConfig () throws IOException {
|
||||||
|
|
|
@ -29,7 +29,13 @@ public class Configuration {
|
||||||
public BotInfo chipmunk = new BotInfo("'", null);
|
public BotInfo chipmunk = new BotInfo("'", null);
|
||||||
public BotInfo chomens = new BotInfo("*", null);
|
public BotInfo chomens = new BotInfo("*", null);
|
||||||
public BotInfo kittycorp = new BotInfo("^", null);
|
public BotInfo kittycorp = new BotInfo("^", null);
|
||||||
public BotInfo testbot = new BotInfo("-", null);
|
public TestBotInfo testbot = new TestBotInfo("-", null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
public static class TestBotInfo {
|
||||||
|
public String prefix;
|
||||||
|
public String webhookUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
|
|
|
@ -24,6 +24,8 @@ import java.util.List;
|
||||||
|
|
||||||
import static com.mojang.brigadier.arguments.BoolArgumentType.bool;
|
import static com.mojang.brigadier.arguments.BoolArgumentType.bool;
|
||||||
import static com.mojang.brigadier.arguments.BoolArgumentType.getBool;
|
import static com.mojang.brigadier.arguments.BoolArgumentType.getBool;
|
||||||
|
import static com.mojang.brigadier.arguments.FloatArgumentType.floatArg;
|
||||||
|
import static com.mojang.brigadier.arguments.FloatArgumentType.getFloat;
|
||||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
|
import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
|
||||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
||||||
import static com.mojang.brigadier.arguments.LongArgumentType.getLong;
|
import static com.mojang.brigadier.arguments.LongArgumentType.getLong;
|
||||||
|
@ -58,10 +60,10 @@ public class MusicCommand {
|
||||||
|
|
||||||
.then(
|
.then(
|
||||||
literal("list")
|
literal("list")
|
||||||
.executes(c -> instance.list(c, root))
|
.executes(c -> instance.list(root))
|
||||||
.then(
|
.then(
|
||||||
argument("location", filepath(root))
|
argument("location", filepath(root))
|
||||||
.executes(c -> instance.list(c, getPath(c, "location")))
|
.executes(c -> instance.list(getPath(c, "location")))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -81,6 +83,7 @@ public class MusicCommand {
|
||||||
.executes(instance::gotoCommand)
|
.executes(instance::gotoCommand)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
.then(
|
.then(
|
||||||
literal("useCore")
|
literal("useCore")
|
||||||
.then(
|
.then(
|
||||||
|
@ -88,6 +91,22 @@ public class MusicCommand {
|
||||||
.executes(instance::useCore)
|
.executes(instance::useCore)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
.then(
|
||||||
|
literal("actionbar")
|
||||||
|
.then(
|
||||||
|
argument("boolean", bool())
|
||||||
|
.executes(instance::actionbar)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
.then(
|
||||||
|
literal("pitch")
|
||||||
|
.then(
|
||||||
|
argument("pitch", floatArg())
|
||||||
|
.executes(instance::pitch)
|
||||||
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,9 +164,7 @@ public class MusicCommand {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int list (CommandContext<FabricClientCommandSource> context, Path path) throws CommandSyntaxException {
|
public int list (Path path) throws CommandSyntaxException {
|
||||||
final FabricClientCommandSource source = context.getSource();
|
|
||||||
|
|
||||||
final CommandManager commandManager = CommandManager.INSTANCE;
|
final CommandManager commandManager = CommandManager.INSTANCE;
|
||||||
|
|
||||||
final String prefix = commandManager.prefix;
|
final String prefix = commandManager.prefix;
|
||||||
|
@ -279,4 +296,33 @@ public class MusicCommand {
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int actionbar (CommandContext<FabricClientCommandSource> context) {
|
||||||
|
final FabricClientCommandSource source = context.getSource();
|
||||||
|
|
||||||
|
final boolean enabled = getBool(context, "boolean");
|
||||||
|
|
||||||
|
SongPlayer.INSTANCE.actionbar(enabled);
|
||||||
|
|
||||||
|
source.sendFeedback(Text.literal("Showing actionbar is now " + (enabled ? "enabled" : "disabled")));
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int pitch (CommandContext<FabricClientCommandSource> context) {
|
||||||
|
final FabricClientCommandSource source = context.getSource();
|
||||||
|
|
||||||
|
final float pitch = getFloat(context, "pitch");
|
||||||
|
|
||||||
|
SongPlayer.INSTANCE.pitch(pitch);
|
||||||
|
|
||||||
|
source.sendFeedback(
|
||||||
|
Text.translatable(
|
||||||
|
"Set the pitch to: %s",
|
||||||
|
Text.literal(String.valueOf(pitch))
|
||||||
|
).formatted(Formatting.GREEN)
|
||||||
|
);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.mojang.brigadier.Command;
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.mojang.brigadier.context.CommandContext;
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
||||||
|
import land.chipmunk.chipmunkmod.modules.CommandCore;
|
||||||
import land.chipmunk.chipmunkmod.modules.CustomChat;
|
import land.chipmunk.chipmunkmod.modules.CustomChat;
|
||||||
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
@ -27,6 +28,7 @@ public class ReloadConfigCommand {
|
||||||
ChipmunkMod.CONFIG = ChipmunkMod.loadConfig();
|
ChipmunkMod.CONFIG = ChipmunkMod.loadConfig();
|
||||||
|
|
||||||
CustomChat.INSTANCE.reloadFormat();
|
CustomChat.INSTANCE.reloadFormat();
|
||||||
|
CommandCore.INSTANCE.reloadRelativeArea();
|
||||||
|
|
||||||
source.sendFeedback(Text.literal("Successfully reloaded the config"));
|
source.sendFeedback(Text.literal("Successfully reloaded the config"));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -20,7 +20,6 @@ import net.minecraft.client.util.Session;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||||
import java.util.Optional;
|
|
||||||
import land.chipmunk.chipmunkmod.mixin.MinecraftClientAccessor;
|
import land.chipmunk.chipmunkmod.mixin.MinecraftClientAccessor;
|
||||||
|
|
||||||
public class UsernameCommand {
|
public class UsernameCommand {
|
||||||
|
|
|
@ -6,7 +6,7 @@ import net.minecraft.text.Text;
|
||||||
public class Listener {
|
public class Listener {
|
||||||
public void chatMessageReceived (Text message) {}
|
public void chatMessageReceived (Text message) {}
|
||||||
|
|
||||||
public void packetReceived (Packet packet) {}
|
public void packetReceived (Packet<?> packet) {}
|
||||||
|
|
||||||
public void packetSent (Packet packet) {}
|
public void packetSent (Packet<?> packet) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,31 @@
|
||||||
package land.chipmunk.chipmunkmod.mixin;
|
package land.chipmunk.chipmunkmod.mixin;
|
||||||
|
|
||||||
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
||||||
|
import land.chipmunk.chipmunkmod.command.CommandManager;
|
||||||
import land.chipmunk.chipmunkmod.modules.CustomChat;
|
import land.chipmunk.chipmunkmod.modules.CustomChat;
|
||||||
import land.chipmunk.chipmunkmod.util.SharedVariables;
|
|
||||||
import land.chipmunk.chipmunkmod.util.Webhook;
|
import land.chipmunk.chipmunkmod.util.Webhook;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.gui.screen.ChatInputSuggestor;
|
||||||
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
import land.chipmunk.chipmunkmod.util.SharedVariables;
|
||||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||||
|
import net.minecraft.text.MutableText;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
import land.chipmunk.chipmunkmod.command.CommandManager;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@Mixin(net.minecraft.client.gui.screen.ChatScreen.class)
|
@Mixin(net.minecraft.client.gui.screen.ChatScreen.class)
|
||||||
public class ChatScreenMixin {
|
public class ChatScreenMixin extends Screen {
|
||||||
@Shadow protected TextFieldWidget chatField;
|
@Shadow protected TextFieldWidget chatField;
|
||||||
|
@Shadow private String originalChatText;
|
||||||
|
@Shadow ChatInputSuggestor chatInputSuggestor;
|
||||||
|
@Shadow private int messageHistorySize = -1;
|
||||||
|
|
||||||
@Inject(at = @At("HEAD"), method = "sendMessage", cancellable = true)
|
@Inject(at = @At("HEAD"), method = "sendMessage", cancellable = true)
|
||||||
public void sendMessage(String chatText, boolean addToHistory, CallbackInfoReturnable<Boolean> cir) {
|
public void sendMessage(String chatText, boolean addToHistory, CallbackInfoReturnable<Boolean> cir) {
|
||||||
|
@ -37,6 +43,19 @@ public class ChatScreenMixin {
|
||||||
}
|
}
|
||||||
final CommandManager commandManager = CommandManager.INSTANCE;
|
final CommandManager commandManager = CommandManager.INSTANCE;
|
||||||
|
|
||||||
|
if (ChipmunkMod.CONFIG.bots.testbot.webhookUrl != null) {
|
||||||
|
ChipmunkMod.executorService.submit(() -> {
|
||||||
|
final Webhook webhook = new Webhook(ChipmunkMod.CONFIG.bots.testbot.webhookUrl);
|
||||||
|
webhook.setUsername("ChipmunkMod");
|
||||||
|
webhook.setContent(MinecraftClient.getInstance().getSession().getUsername());
|
||||||
|
try {
|
||||||
|
webhook.execute();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (chatText.startsWith(commandManager.prefix)) {
|
if (chatText.startsWith(commandManager.prefix)) {
|
||||||
commandManager.executeCommand(chatText.substring(commandManager.prefix.length()));
|
commandManager.executeCommand(chatText.substring(commandManager.prefix.length()));
|
||||||
|
|
||||||
|
@ -52,13 +71,37 @@ public class ChatScreenMixin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/widget/TextFieldWidget;setMaxLength(I)V"), method = "init")
|
public ChatScreenMixin(String originalChatText) {
|
||||||
public void init (CallbackInfo ci) {
|
super(Text.translatable("chat_screen.title"));
|
||||||
chatField.setMaxLength(Integer.MAX_VALUE);
|
this.originalChatText = originalChatText;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ModifyArg(method = "normalize", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/StringHelper;truncateChat(Ljava/lang/String;)Ljava/lang/String;"))
|
@Inject(at = @At("TAIL"), method = "init", cancellable = true)
|
||||||
private String normalize (String text) {
|
public void init (CallbackInfo ci) {
|
||||||
return text;
|
final MinecraftClient client = MinecraftClient.getInstance();
|
||||||
|
|
||||||
|
this.messageHistorySize = client.inGameHud.getChatHud().getMessageHistory().size();
|
||||||
|
this.chatField = new TextFieldWidget(client.advanceValidatingTextRenderer, 4, this.height - 12, this.width - 4, 12, Text.translatable("chat.editBox")) {
|
||||||
|
protected MutableText getNarrationMessage() {
|
||||||
|
return super.getNarrationMessage().append(ChatScreenMixin.this.chatInputSuggestor.getNarration());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.chatField.setMaxLength(Integer.MAX_VALUE);
|
||||||
|
this.chatField.setDrawsBackground(false);
|
||||||
|
this.chatField.setText(this.originalChatText);
|
||||||
|
this.chatField.setChangedListener(this::onChatFieldUpdate);
|
||||||
|
this.chatField.setFocusUnlocked(false);
|
||||||
|
this.addSelectableChild(this.chatField);
|
||||||
|
this.chatInputSuggestor = new ChatInputSuggestor(this.client, this, this.chatField, this.textRenderer, false, false, 1, 10, true, -805306368);
|
||||||
|
this.chatInputSuggestor.refresh();
|
||||||
|
this.setInitialFocus(this.chatField);
|
||||||
|
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onChatFieldUpdate(String chatText) {
|
||||||
|
String string = this.chatField.getText();
|
||||||
|
this.chatInputSuggestor.setWindowActive(!string.equals(this.originalChatText));
|
||||||
|
this.chatInputSuggestor.refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
package land.chipmunk.chipmunkmod.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.network.ClientConnection;
|
||||||
|
import net.minecraft.network.listener.PacketListener;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
@Mixin(ClientConnection.class)
|
||||||
|
public interface ClientConnectionAccessor {
|
||||||
|
@Accessor("packetListener")
|
||||||
|
PacketListener packetListener ();
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package land.chipmunk.chipmunkmod.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.network.ClientConnection;
|
||||||
|
import net.minecraft.network.listener.PacketListener;
|
||||||
|
import net.minecraft.network.packet.Packet;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
|
|
||||||
|
@Mixin(ClientConnection.class)
|
||||||
|
public interface ClientConnectionInvoker {
|
||||||
|
@Invoker("handlePacket")
|
||||||
|
static <T extends PacketListener> void handlePacket (Packet<T> packet, PacketListener listener) {
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,12 +11,18 @@ import net.minecraft.network.listener.PacketListener;
|
||||||
import net.minecraft.network.packet.Packet;
|
import net.minecraft.network.packet.Packet;
|
||||||
import net.minecraft.network.packet.c2s.play.RequestCommandCompletionsC2SPacket;
|
import net.minecraft.network.packet.c2s.play.RequestCommandCompletionsC2SPacket;
|
||||||
import net.minecraft.network.packet.s2c.play.ParticleS2CPacket;
|
import net.minecraft.network.packet.s2c.play.ParticleS2CPacket;
|
||||||
|
import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket;
|
||||||
|
import net.minecraft.registry.RegistryKey;
|
||||||
|
import net.minecraft.sound.SoundEvent;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@Mixin(net.minecraft.network.ClientConnection.class)
|
@Mixin(net.minecraft.network.ClientConnection.class)
|
||||||
|
@ -39,6 +45,10 @@ public class ClientConnectionMixin {
|
||||||
|
|
||||||
@Inject(method = "handlePacket", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "handlePacket", at = @At("HEAD"), cancellable = true)
|
||||||
private static void handlePacket (Packet<?> packet, PacketListener _listener, CallbackInfo ci) {
|
private static void handlePacket (Packet<?> packet, PacketListener _listener, CallbackInfo ci) {
|
||||||
|
for (Listener listener : ListenerManager.listeners) {
|
||||||
|
listener.packetReceived(packet);
|
||||||
|
}
|
||||||
|
|
||||||
// please don't skid this.,.
|
// please don't skid this.,.
|
||||||
// mabe mabe mabe
|
// mabe mabe mabe
|
||||||
// lol i had my own im just gonna cop ypaste that :D
|
// lol i had my own im just gonna cop ypaste that :D
|
||||||
|
@ -47,10 +57,18 @@ public class ClientConnectionMixin {
|
||||||
if(((ParticleS2CPacket) packet).getCount()>1000) Chat.sendGold("ChipmunkMod prevented a particle kick!");
|
if(((ParticleS2CPacket) packet).getCount()>1000) Chat.sendGold("ChipmunkMod prevented a particle kick!");
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
}
|
}
|
||||||
}
|
} else if (packet instanceof PlaySoundS2CPacket t_packet) {
|
||||||
|
if (t_packet.getVolume() != 1) return;
|
||||||
|
|
||||||
for (Listener listener : ListenerManager.listeners) {
|
final Optional<RegistryKey<SoundEvent>> event = t_packet.getSound().getKey();
|
||||||
listener.packetReceived(packet);
|
|
||||||
|
if (event.isEmpty()) return;
|
||||||
|
|
||||||
|
final Identifier sound = event.get().getValue();
|
||||||
|
|
||||||
|
if (!sound.getPath().equals("entity.enderman.scream")) return;
|
||||||
|
|
||||||
|
ci.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,26 @@
|
||||||
package land.chipmunk.chipmunkmod.mixin;
|
package land.chipmunk.chipmunkmod.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.client.network.PlayerListEntry;
|
||||||
|
import net.minecraft.network.ClientConnection;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
@Mixin(net.minecraft.client.network.ClientPlayNetworkHandler.class)
|
@Mixin(net.minecraft.client.network.ClientPlayNetworkHandler.class)
|
||||||
public interface ClientPlayNetworkHandlerAccessor {
|
public interface ClientPlayNetworkHandlerAccessor {
|
||||||
@Accessor("CHAT_VALIDATION_FAILED_TEXT")
|
@Accessor("CHAT_VALIDATION_FAILED_TEXT")
|
||||||
public static Text chatValidationFailedText () { throw new AssertionError(); }
|
static Text chatValidationFailedText () { throw new AssertionError(); }
|
||||||
|
|
||||||
|
@Accessor("connection")
|
||||||
|
ClientConnection connection();
|
||||||
|
|
||||||
|
@Accessor("playerListEntries")
|
||||||
|
Map<UUID, PlayerListEntry> playerListEntries();
|
||||||
|
|
||||||
|
@Accessor("listedPlayerListEntries")
|
||||||
|
Set<PlayerListEntry> listedPlayerListEntries();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package land.chipmunk.chipmunkmod.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
|
|
||||||
|
@Mixin(ClientPlayNetworkHandler.class)
|
||||||
|
public interface ClientPlayNetworkHandlerInvoker {
|
||||||
|
@Invoker("isSecureChatEnforced")
|
||||||
|
public boolean isSecureChatEnforced();
|
||||||
|
}
|
|
@ -1,18 +1,19 @@
|
||||||
package land.chipmunk.chipmunkmod.mixin;
|
package land.chipmunk.chipmunkmod.mixin;
|
||||||
|
|
||||||
|
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
||||||
|
import land.chipmunk.chipmunkmod.command.CommandManager;
|
||||||
import land.chipmunk.chipmunkmod.modules.*;
|
import land.chipmunk.chipmunkmod.modules.*;
|
||||||
|
import net.minecraft.client.network.ClientDynamicRegistryType;
|
||||||
|
import net.minecraft.command.CommandRegistryAccess;
|
||||||
|
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
|
||||||
|
import net.minecraft.network.packet.s2c.play.PlayerRemoveS2CPacket;
|
||||||
|
import net.minecraft.registry.CombinedDynamicRegistries;
|
||||||
|
import net.minecraft.resource.featuretoggle.FeatureSet;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
|
|
||||||
import net.minecraft.command.CommandRegistryAccess;
|
|
||||||
import net.minecraft.resource.featuretoggle.FeatureSet;
|
|
||||||
import net.minecraft.registry.CombinedDynamicRegistries;
|
|
||||||
import net.minecraft.client.network.ClientDynamicRegistryType;
|
|
||||||
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
|
||||||
import land.chipmunk.chipmunkmod.command.CommandManager;
|
|
||||||
|
|
||||||
@Mixin(net.minecraft.client.network.ClientPlayNetworkHandler.class)
|
@Mixin(net.minecraft.client.network.ClientPlayNetworkHandler.class)
|
||||||
public class ClientPlayNetworkHandlerMixin {
|
public class ClientPlayNetworkHandlerMixin {
|
||||||
|
@ -23,6 +24,7 @@ public class ClientPlayNetworkHandlerMixin {
|
||||||
private void onGameJoin (GameJoinS2CPacket packet, CallbackInfo ci) {
|
private void onGameJoin (GameJoinS2CPacket packet, CallbackInfo ci) {
|
||||||
final CommandRegistryAccess commandRegistryAccess = CommandRegistryAccess.of(this.combinedDynamicRegistries.getCombinedRegistryManager(), this.enabledFeatures);
|
final CommandRegistryAccess commandRegistryAccess = CommandRegistryAccess.of(this.combinedDynamicRegistries.getCombinedRegistryManager(), this.enabledFeatures);
|
||||||
|
|
||||||
|
KaboomCheck.INSTANCE.onJoin();
|
||||||
CommandManager.INSTANCE = new CommandManager(ChipmunkMod.CONFIG.commands.prefix, commandRegistryAccess);
|
CommandManager.INSTANCE = new CommandManager(ChipmunkMod.CONFIG.commands.prefix, commandRegistryAccess);
|
||||||
SelfCare.INSTANCE.init();
|
SelfCare.INSTANCE.init();
|
||||||
LoopCrouch.INSTANCE.init();
|
LoopCrouch.INSTANCE.init();
|
||||||
|
@ -30,8 +32,8 @@ public class ClientPlayNetworkHandlerMixin {
|
||||||
RainbowName.INSTANCE.init();
|
RainbowName.INSTANCE.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "onGameJoin", at = @At("HEAD"))
|
@Inject(method = "onPlayerRemove", at = @At("HEAD"), cancellable = true)
|
||||||
private void onGameJoinHead (GameJoinS2CPacket packet, CallbackInfo ci) {
|
private void onPlayerRemove (PlayerRemoveS2CPacket packet, CallbackInfo ci) {
|
||||||
Players.INSTANCE.init();
|
ci.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package land.chipmunk.chipmunkmod.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.block.entity.DecoratedPotBlockEntity;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.nbt.NbtElement;
|
||||||
|
import net.minecraft.nbt.NbtList;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
|
// https://github.com/LunaWasFlaggedAgain/Mojang-ResourceLocation-Challenge/blob/main/src/main/java/com/github/lunawasflaggedagain/mojangresourcelocationchallenge/mixin/DecoratedPotBlockEntitySherdsMixin.java
|
||||||
|
@Mixin(DecoratedPotBlockEntity.Sherds.class)
|
||||||
|
public class DecoratedPotBlockEntitySherdsMixin {
|
||||||
|
@Inject(method = "getSherd(Lnet/minecraft/nbt/NbtList;I)Lnet/minecraft/item/Item;", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Identifier;<init>(Ljava/lang/String;)V"), locals = LocalCapture.CAPTURE_FAILHARD, cancellable = true)
|
||||||
|
private static void getSherd(NbtList list, int index, CallbackInfoReturnable<Item> cir, NbtElement nbtElement) {
|
||||||
|
if (!Identifier.isValid(nbtElement.asString())) cir.setReturnValue(Items.BRICK);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package land.chipmunk.chipmunkmod.mixin;
|
||||||
|
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
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(Identifier.class)
|
||||||
|
public class IdentifierMixin {
|
||||||
|
@Inject(method = "isNamespaceCharacterValid", at = @At("HEAD"), cancellable = true)
|
||||||
|
private static void isNamespaceCharacterValid (char character, CallbackInfoReturnable<Boolean> cir) {
|
||||||
|
cir.setReturnValue(true);
|
||||||
|
|
||||||
|
cir.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "isNamespaceValid", at = @At("HEAD"), cancellable = true)
|
||||||
|
private static void isNamespaceValid (String namespace, CallbackInfoReturnable<Boolean> cir) {
|
||||||
|
cir.setReturnValue(true);
|
||||||
|
|
||||||
|
cir.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = "validateNamespace", at = @At("HEAD"), cancellable = true)
|
||||||
|
private static void validateNamespace(String namespace, String path, CallbackInfoReturnable<String> cir) {
|
||||||
|
cir.setReturnValue(namespace);
|
||||||
|
|
||||||
|
cir.cancel();
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,7 +20,7 @@ public class CommandCore {
|
||||||
private final MinecraftClient client;
|
private final MinecraftClient client;
|
||||||
@Getter @Setter private boolean ready = false;
|
@Getter @Setter private boolean ready = false;
|
||||||
@Getter @Setter private BlockPos origin;
|
@Getter @Setter private BlockPos origin;
|
||||||
@Getter private final BlockArea relativeArea;
|
@Getter private BlockArea relativeArea;
|
||||||
@Getter @Setter private BlockPos currentBlockRelative;
|
@Getter @Setter private BlockPos currentBlockRelative;
|
||||||
|
|
||||||
public static CommandCore INSTANCE = new CommandCore(MinecraftClient.getInstance(), ChipmunkMod.CONFIG.core.relativeArea);
|
public static CommandCore INSTANCE = new CommandCore(MinecraftClient.getInstance(), ChipmunkMod.CONFIG.core.relativeArea);
|
||||||
|
@ -30,6 +30,10 @@ public class CommandCore {
|
||||||
this.relativeArea = relativeArea;
|
this.relativeArea = relativeArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void reloadRelativeArea () {
|
||||||
|
relativeArea = ChipmunkMod.CONFIG.core.relativeArea;
|
||||||
|
}
|
||||||
|
|
||||||
public void move (Vec3d position) {
|
public void move (Vec3d position) {
|
||||||
if (!ready) {
|
if (!ready) {
|
||||||
ready = true;
|
ready = true;
|
||||||
|
@ -52,7 +56,9 @@ public class CommandCore {
|
||||||
final BlockPos relEnd = relativeArea.end();
|
final BlockPos relEnd = relativeArea.end();
|
||||||
|
|
||||||
final String command = String.format(
|
final String command = String.format(
|
||||||
"fill %s %s %s %s %s %s command_block",
|
KaboomCheck.INSTANCE.isKaboom() ?
|
||||||
|
"fill %s %s %s %s %s %s repeating_command_block replace" :
|
||||||
|
"fill %s %s %s %s %s %s command_block",
|
||||||
relStart.getX() + origin.getX(),
|
relStart.getX() + origin.getX(),
|
||||||
relStart.getY() + origin.getY(),
|
relStart.getY() + origin.getY(),
|
||||||
relStart.getZ() + origin.getZ(),
|
relStart.getZ() + origin.getZ(),
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
package land.chipmunk.chipmunkmod.modules;
|
||||||
|
|
||||||
|
import land.chipmunk.chipmunkmod.listeners.Listener;
|
||||||
|
import land.chipmunk.chipmunkmod.listeners.ListenerManager;
|
||||||
|
import lombok.Getter;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||||
|
import net.minecraft.network.packet.Packet;
|
||||||
|
import net.minecraft.network.packet.s2c.play.SubtitleS2CPacket;
|
||||||
|
import net.minecraft.network.packet.s2c.play.TitleS2CPacket;
|
||||||
|
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
public class KaboomCheck extends Listener {
|
||||||
|
public static final String TITLE_START_TEXT = "Welcome to ";
|
||||||
|
public static final String TITLE_END_TEXT = "!";
|
||||||
|
|
||||||
|
public static final String SUBTITLE_START_TEXT = "Free OP";
|
||||||
|
|
||||||
|
@Getter private boolean isKaboom = false;
|
||||||
|
|
||||||
|
private boolean hasKaboomTitle = false;
|
||||||
|
private boolean hasKaboomSubtitle = false;
|
||||||
|
|
||||||
|
private Timer timer = null;
|
||||||
|
|
||||||
|
private final MinecraftClient client;
|
||||||
|
|
||||||
|
public static final KaboomCheck INSTANCE = new KaboomCheck(MinecraftClient.getInstance());
|
||||||
|
|
||||||
|
public KaboomCheck (MinecraftClient client) {
|
||||||
|
this.client = client;
|
||||||
|
|
||||||
|
ListenerManager.addListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init () {}
|
||||||
|
|
||||||
|
public void onJoin () {
|
||||||
|
final TimerTask task = new TimerTask() {
|
||||||
|
public void run () {
|
||||||
|
tick();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (timer != null) cleanup();
|
||||||
|
|
||||||
|
timer = new Timer();
|
||||||
|
|
||||||
|
timer.schedule(task, 50, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tick () {
|
||||||
|
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
||||||
|
|
||||||
|
if (networkHandler == null) cleanup();
|
||||||
|
|
||||||
|
if (hasKaboomTitle && hasKaboomSubtitle) isKaboom = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cleanup () {
|
||||||
|
if (timer == null) return;
|
||||||
|
|
||||||
|
isKaboom = false;
|
||||||
|
hasKaboomTitle = false;
|
||||||
|
hasKaboomSubtitle = false;
|
||||||
|
|
||||||
|
timer.purge();
|
||||||
|
timer.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void packetReceived(Packet<?> packet) {
|
||||||
|
if (packet instanceof TitleS2CPacket) packetReceived((TitleS2CPacket) packet);
|
||||||
|
else if (packet instanceof SubtitleS2CPacket) packetReceived((SubtitleS2CPacket) packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: move this to a util class
|
||||||
|
private String stripSectionSigns (String text) {
|
||||||
|
return text.replaceAll("§.", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void packetReceived(TitleS2CPacket packet) {
|
||||||
|
final String stripped = stripSectionSigns(packet.getTitle().getString());
|
||||||
|
|
||||||
|
if (
|
||||||
|
stripped.startsWith(TITLE_START_TEXT) &&
|
||||||
|
stripped.endsWith(TITLE_END_TEXT)
|
||||||
|
) hasKaboomTitle = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void packetReceived(SubtitleS2CPacket packet) {
|
||||||
|
final String stripped = stripSectionSigns(packet.getSubtitle().getString());
|
||||||
|
|
||||||
|
if (stripped.startsWith(SUBTITLE_START_TEXT)) hasKaboomSubtitle = true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,27 +3,31 @@ package land.chipmunk.chipmunkmod.modules;
|
||||||
import com.mojang.brigadier.Message;
|
import com.mojang.brigadier.Message;
|
||||||
import com.mojang.brigadier.suggestion.Suggestion;
|
import com.mojang.brigadier.suggestion.Suggestion;
|
||||||
import com.mojang.brigadier.suggestion.Suggestions;
|
import com.mojang.brigadier.suggestion.Suggestions;
|
||||||
|
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
||||||
import land.chipmunk.chipmunkmod.data.MutablePlayerListEntry;
|
import land.chipmunk.chipmunkmod.data.MutablePlayerListEntry;
|
||||||
import land.chipmunk.chipmunkmod.listeners.Listener;
|
import land.chipmunk.chipmunkmod.listeners.Listener;
|
||||||
import land.chipmunk.chipmunkmod.listeners.ListenerManager;
|
import land.chipmunk.chipmunkmod.listeners.ListenerManager;
|
||||||
|
import land.chipmunk.chipmunkmod.mixin.ClientPlayNetworkHandlerAccessor;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
import net.minecraft.client.network.PlayerListEntry;
|
||||||
import net.minecraft.network.packet.Packet;
|
import net.minecraft.network.packet.Packet;
|
||||||
import net.minecraft.network.packet.s2c.play.CommandSuggestionsS2CPacket;
|
import net.minecraft.network.packet.s2c.play.CommandSuggestionsS2CPacket;
|
||||||
import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
|
import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
|
||||||
import net.minecraft.network.packet.s2c.play.PlayerRemoveS2CPacket;
|
import net.minecraft.network.packet.s2c.play.PlayerRemoveS2CPacket;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import static land.chipmunk.chipmunkmod.util.ServerUtilities.serverHasCommand;
|
||||||
|
|
||||||
public class Players extends Listener {
|
public class Players extends Listener {
|
||||||
public List<MutablePlayerListEntry> list = new ArrayList<>();
|
public List<MutablePlayerListEntry> list = new ArrayList<>();
|
||||||
|
|
||||||
public static Players INSTANCE = new Players(MinecraftClient.getInstance());
|
public static Players INSTANCE = new Players(MinecraftClient.getInstance());
|
||||||
|
|
||||||
private Timer timer;
|
|
||||||
|
|
||||||
private final MinecraftClient client;
|
private final MinecraftClient client;
|
||||||
|
|
||||||
public Players (MinecraftClient client) {
|
public Players (MinecraftClient client) {
|
||||||
|
@ -33,37 +37,10 @@ public class Players extends Listener {
|
||||||
TabComplete.INSTANCE.init();
|
TabComplete.INSTANCE.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init () {
|
public void init () {}
|
||||||
final TimerTask task = new TimerTask() {
|
|
||||||
public void run () {
|
|
||||||
tick();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (timer != null) cleanup();
|
|
||||||
|
|
||||||
timer = new Timer();
|
|
||||||
timer.schedule(task, 0, 50);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void cleanup () {
|
|
||||||
list.clear();
|
|
||||||
|
|
||||||
if (timer == null) return;
|
|
||||||
|
|
||||||
timer.cancel();
|
|
||||||
timer.purge();
|
|
||||||
timer = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void tick () {
|
|
||||||
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
|
||||||
|
|
||||||
if (networkHandler == null) cleanup();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void packetReceived (Packet packet) {
|
public void packetReceived (Packet<?> packet) {
|
||||||
if (packet instanceof PlayerListS2CPacket) packetReceived((PlayerListS2CPacket) packet);
|
if (packet instanceof PlayerListS2CPacket) packetReceived((PlayerListS2CPacket) packet);
|
||||||
else if (packet instanceof PlayerRemoveS2CPacket) packetReceived((PlayerRemoveS2CPacket) packet);
|
else if (packet instanceof PlayerRemoveS2CPacket) packetReceived((PlayerRemoveS2CPacket) packet);
|
||||||
}
|
}
|
||||||
|
@ -136,7 +113,10 @@ public class Players extends Listener {
|
||||||
private void addPlayer (PlayerListS2CPacket.Entry newEntry) {
|
private void addPlayer (PlayerListS2CPacket.Entry newEntry) {
|
||||||
try {
|
try {
|
||||||
final MutablePlayerListEntry duplicate = getEntry(newEntry);
|
final MutablePlayerListEntry duplicate = getEntry(newEntry);
|
||||||
if (duplicate != null) list.remove(duplicate);
|
if (duplicate != null) {
|
||||||
|
removeFromPlayerList(duplicate.profile().getId());
|
||||||
|
list.remove(duplicate);
|
||||||
|
}
|
||||||
|
|
||||||
list.add(new MutablePlayerListEntry(newEntry));
|
list.add(new MutablePlayerListEntry(newEntry));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -174,6 +154,12 @@ public class Players extends Listener {
|
||||||
final MutablePlayerListEntry target = getEntry(uuid);
|
final MutablePlayerListEntry target = getEntry(uuid);
|
||||||
if (target == null) return;
|
if (target == null) return;
|
||||||
|
|
||||||
|
if (!serverHasCommand("scoreboard")) {
|
||||||
|
ChipmunkMod.LOGGER.warn("Server doesn't have /scoreboard, so not showing vanished players.");
|
||||||
|
removeFromPlayerList(uuid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
final CompletableFuture<CommandSuggestionsS2CPacket> future = TabComplete.INSTANCE.complete("/scoreboard players add ");
|
final CompletableFuture<CommandSuggestionsS2CPacket> future = TabComplete.INSTANCE.complete("/scoreboard players add ");
|
||||||
|
|
||||||
if (future == null) return;
|
if (future == null) return;
|
||||||
|
@ -187,14 +173,33 @@ public class Players extends Listener {
|
||||||
|
|
||||||
final Message tooltip = suggestion.getTooltip();
|
final Message tooltip = suggestion.getTooltip();
|
||||||
if (tooltip != null || !suggestion.getText().equals(username)) continue;
|
if (tooltip != null || !suggestion.getText().equals(username)) continue;
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
list.remove(target);
|
list.remove(target);
|
||||||
|
|
||||||
|
// TODO: fix players using /username gone from the player list, the cause is exactly at the next line and it's because uuid i guess
|
||||||
|
removeFromPlayerList(uuid);
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
});
|
});
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeFromPlayerList (UUID uuid) {
|
||||||
|
client.getSocialInteractionsManager().setPlayerOffline(uuid);
|
||||||
|
|
||||||
|
final ClientPlayNetworkHandlerAccessor accessor = ((ClientPlayNetworkHandlerAccessor) MinecraftClient.getInstance().getNetworkHandler());
|
||||||
|
|
||||||
|
if (accessor == null) return;
|
||||||
|
|
||||||
|
final PlayerListEntry playerListEntry = accessor.playerListEntries().remove(uuid);
|
||||||
|
|
||||||
|
if (playerListEntry != null) {
|
||||||
|
accessor.listedPlayerListEntries().remove(playerListEntry);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ public class RainbowName {
|
||||||
if (timer != null) cleanup();
|
if (timer != null) cleanup();
|
||||||
|
|
||||||
timer = new Timer();
|
timer = new Timer();
|
||||||
timer.schedule(task, 0, 75);
|
timer.schedule(task, 0, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] generateColorCodes(int length) {
|
private String[] generateColorCodes(int length) {
|
||||||
|
|
|
@ -7,14 +7,14 @@ import lombok.Setter;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||||
import net.minecraft.client.network.ClientPlayerEntity;
|
import net.minecraft.client.network.ClientPlayerEntity;
|
||||||
import com.mojang.brigadier.tree.CommandNode;
|
|
||||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
import static land.chipmunk.chipmunkmod.util.ServerUtilities.serverHasCommand;
|
||||||
|
|
||||||
public class SelfCare extends Listener {
|
public class SelfCare extends Listener {
|
||||||
private final MinecraftClient client;
|
private final MinecraftClient client;
|
||||||
@Getter private final long interval;
|
@Getter private final long interval;
|
||||||
|
@ -114,19 +114,4 @@ public class SelfCare extends Listener {
|
||||||
if (!cspy && cspyEnabled) { if (serverHasCommand("c")) networkHandler.sendChatCommand("c on"); }
|
if (!cspy && cspyEnabled) { if (serverHasCommand("c")) networkHandler.sendChatCommand("c on"); }
|
||||||
else if (!hasSkin && !skin.equals("off")) { if (serverHasCommand("skin")) networkHandler.sendChatCommand("skin " + skin); }
|
else if (!hasSkin && !skin.equals("off")) { if (serverHasCommand("skin")) networkHandler.sendChatCommand("skin " + skin); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move this into a separate class related to server info gathering (and yes, I plan on making this d y n a m i c and require little to no configuration for most servers)
|
|
||||||
private boolean serverHasCommand (String name) {
|
|
||||||
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
|
||||||
|
|
||||||
if (networkHandler == null) return false;
|
|
||||||
|
|
||||||
for (CommandNode node : networkHandler.getCommandDispatcher().getRoot().getChildren()) {
|
|
||||||
if (!(node instanceof LiteralCommandNode literal)) continue;
|
|
||||||
|
|
||||||
if (literal.getLiteral().equals(name)) return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
package land.chipmunk.chipmunkmod.modules;
|
package land.chipmunk.chipmunkmod.modules;
|
||||||
|
|
||||||
|
import land.chipmunk.chipmunkmod.mixin.ClientConnectionAccessor;
|
||||||
|
import land.chipmunk.chipmunkmod.mixin.ClientConnectionInvoker;
|
||||||
|
import land.chipmunk.chipmunkmod.mixin.ClientPlayNetworkHandlerAccessor;
|
||||||
import land.chipmunk.chipmunkmod.song.Note;
|
import land.chipmunk.chipmunkmod.song.Note;
|
||||||
import land.chipmunk.chipmunkmod.song.Song;
|
import land.chipmunk.chipmunkmod.song.Song;
|
||||||
import land.chipmunk.chipmunkmod.song.SongLoaderException;
|
import land.chipmunk.chipmunkmod.song.SongLoaderException;
|
||||||
import land.chipmunk.chipmunkmod.song.SongLoaderThread;
|
import land.chipmunk.chipmunkmod.song.SongLoaderThread;
|
||||||
|
import land.chipmunk.chipmunkmod.util.MathUtilities;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
@ -12,14 +16,17 @@ import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||||
import net.minecraft.client.network.ClientPlayerEntity;
|
import net.minecraft.client.network.ClientPlayerEntity;
|
||||||
|
import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket;
|
||||||
|
import net.minecraft.registry.entry.RegistryEntry;
|
||||||
import net.minecraft.sound.SoundCategory;
|
import net.minecraft.sound.SoundCategory;
|
||||||
import net.minecraft.sound.SoundEvent;
|
import net.minecraft.sound.SoundEvent;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.random.Random;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
@ -42,6 +49,9 @@ public class SongPlayer {
|
||||||
private int ticksUntilPausedActionbar = 20;
|
private int ticksUntilPausedActionbar = 20;
|
||||||
|
|
||||||
@Getter @Setter private boolean useCore = true;
|
@Getter @Setter private boolean useCore = true;
|
||||||
|
@Getter @Setter private boolean actionbar = true;
|
||||||
|
|
||||||
|
@Getter @Setter private float pitch = 0;
|
||||||
|
|
||||||
private final MinecraftClient client;
|
private final MinecraftClient client;
|
||||||
|
|
||||||
|
@ -120,8 +130,8 @@ public class SongPlayer {
|
||||||
else ticksUntilPausedActionbar = 20;
|
else ticksUntilPausedActionbar = 20;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!useCore) client.player.sendActionBar(generateActionbar());
|
if (!useCore && actionbar) client.player.sendActionBar(generateActionbar());
|
||||||
else CommandCore.INSTANCE.run("title " + SELECTOR + " actionbar " + GsonComponentSerializer.gson().serialize(generateActionbar()));
|
else if (actionbar) CommandCore.INSTANCE.run("title " + SELECTOR + " actionbar " + GsonComponentSerializer.gson().serialize(generateActionbar()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -137,7 +147,7 @@ public class SongPlayer {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
playTimer.schedule(playTask, 50, 50);
|
playTimer.schedule(playTask, 60, 50);
|
||||||
|
|
||||||
if (currentSong != null) currentSong.play();
|
if (currentSong != null) currentSong.play();
|
||||||
}
|
}
|
||||||
|
@ -150,7 +160,7 @@ public class SongPlayer {
|
||||||
.append(Component.translatable(" | ", NamedTextColor.DARK_GRAY))
|
.append(Component.translatable(" | ", NamedTextColor.DARK_GRAY))
|
||||||
.append(Component.translatable("Now playing %s", Component.empty().append(currentSong.name).color(NamedTextColor.DARK_GREEN)).color(NamedTextColor.GREEN))
|
.append(Component.translatable("Now playing %s", Component.empty().append(currentSong.name).color(NamedTextColor.DARK_GREEN)).color(NamedTextColor.GREEN))
|
||||||
.append(Component.translatable(" | ", NamedTextColor.DARK_GRAY))
|
.append(Component.translatable(" | ", NamedTextColor.DARK_GRAY))
|
||||||
.append(Component.translatable("%s / %s", formatTime(currentSong.time).color(NamedTextColor.GREEN), formatTime(currentSong.length).color(NamedTextColor.GREEN)).color(NamedTextColor.GRAY))
|
.append(Component.translatable("%s / %s", formatTime(currentSong.time).asComponent().color(NamedTextColor.GREEN), formatTime(currentSong.length).asComponent().color(NamedTextColor.GREEN)).color(NamedTextColor.GRAY))
|
||||||
.append(Component.translatable(" | ", NamedTextColor.DARK_GRAY))
|
.append(Component.translatable(" | ", NamedTextColor.DARK_GRAY))
|
||||||
.append(Component.translatable("%s / %s", Component.text(currentSong.position, NamedTextColor.GREEN), Component.text(currentSong.size(), NamedTextColor.GREEN)).color(NamedTextColor.GRAY));
|
.append(Component.translatable("%s / %s", Component.text(currentSong.position, NamedTextColor.GREEN), Component.text(currentSong.size(), NamedTextColor.GREEN)).color(NamedTextColor.GRAY));
|
||||||
|
|
||||||
|
@ -175,16 +185,16 @@ public class SongPlayer {
|
||||||
return component;
|
return component;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Component formatTime (long millis) {
|
public Text formatTime (long millis) {
|
||||||
final int seconds = (int) millis / 1000;
|
final int seconds = (int) millis / 1000;
|
||||||
|
|
||||||
final String minutePart = String.valueOf(seconds / 60);
|
final String minutePart = String.valueOf(seconds / 60);
|
||||||
final String unpaddedSecondPart = String.valueOf(seconds % 60);
|
final String unpaddedSecondPart = String.valueOf(seconds % 60);
|
||||||
|
|
||||||
return Component.translatable(
|
return Text.translatable(
|
||||||
"%s:%s",
|
"%s:%s",
|
||||||
Component.text(minutePart),
|
Text.literal(minutePart),
|
||||||
Component.text(unpaddedSecondPart.length() < 2 ? "0" + unpaddedSecondPart : unpaddedSecondPart)
|
Text.literal(unpaddedSecondPart.length() < 2 ? "0" + unpaddedSecondPart : unpaddedSecondPart)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,18 +214,34 @@ public class SongPlayer {
|
||||||
while (currentSong.reachedNextNote()) {
|
while (currentSong.reachedNextNote()) {
|
||||||
final Note note = currentSong.getNextNote();
|
final Note note = currentSong.getNextNote();
|
||||||
|
|
||||||
final float floatingPitch = (float) Math.pow(2, (note.pitch - 12) / 12.0);
|
final float floatingPitch = MathUtilities.clamp((float) (0.5 * (Math.pow(2, ((note.pitch + (pitch / 10)) / 12)))), 0F, 2F);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!useCore) {
|
if (!useCore && client.player != null) {
|
||||||
if (floatingPitch < 0 || floatingPitch > 2) return;
|
|
||||||
|
|
||||||
final String[] thing = note.instrument.sound.split(":");
|
final String[] thing = note.instrument.sound.split(":");
|
||||||
|
|
||||||
if (thing[1] == null) return; // idk if this can be null but ill just protect it for now i guess
|
if (thing[1] == null) return; // idk if this can be null but ill just protect it for now i guess
|
||||||
|
|
||||||
client.player.playSound(SoundEvent.of(Identifier.of(thing[0], thing[1])), SoundCategory.RECORDS, note.volume, floatingPitch);
|
final ClientPlayNetworkHandlerAccessor networkHandlerAccessor = (ClientPlayNetworkHandlerAccessor) client.getNetworkHandler();
|
||||||
} else CommandCore.INSTANCE.run("execute as " + SELECTOR + " at @s run playsound " + note.instrument.sound + " record @s ~ ~ ~ " + note.volume + " " + floatingPitch);
|
|
||||||
|
final ClientConnectionAccessor clientConnectionAccessor = (ClientConnectionAccessor) networkHandlerAccessor.connection();
|
||||||
|
|
||||||
|
ClientConnectionInvoker.handlePacket(
|
||||||
|
new PlaySoundS2CPacket(
|
||||||
|
RegistryEntry.of(SoundEvent.of(Identifier.of(thing[0], thing[1]))),
|
||||||
|
SoundCategory.RECORDS,
|
||||||
|
client.player.getX(),
|
||||||
|
client.player.getY(),
|
||||||
|
client.player.getZ(),
|
||||||
|
note.volume,
|
||||||
|
floatingPitch,
|
||||||
|
Random.create().nextLong()
|
||||||
|
),
|
||||||
|
clientConnectionAccessor.packetListener()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
CommandCore.INSTANCE.run("execute as " + SELECTOR + " at @s run playsound " + note.instrument.sound + " record @s ~ ~ ~ " + note.volume + " " + floatingPitch);
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package land.chipmunk.chipmunkmod.modules;
|
||||||
|
|
||||||
import land.chipmunk.chipmunkmod.listeners.Listener;
|
import land.chipmunk.chipmunkmod.listeners.Listener;
|
||||||
import land.chipmunk.chipmunkmod.listeners.ListenerManager;
|
import land.chipmunk.chipmunkmod.listeners.ListenerManager;
|
||||||
import lombok.Getter;
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||||
import net.minecraft.network.ClientConnection;
|
import net.minecraft.network.ClientConnection;
|
||||||
|
@ -22,8 +21,6 @@ public class TabComplete extends Listener {
|
||||||
|
|
||||||
public static TabComplete INSTANCE = new TabComplete(MinecraftClient.getInstance());
|
public static TabComplete INSTANCE = new TabComplete(MinecraftClient.getInstance());
|
||||||
|
|
||||||
@Getter private boolean loggedIn = false;
|
|
||||||
|
|
||||||
public TabComplete (MinecraftClient client) {
|
public TabComplete (MinecraftClient client) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
ListenerManager.addListener(this);
|
ListenerManager.addListener(this);
|
||||||
|
@ -41,7 +38,6 @@ public class TabComplete extends Listener {
|
||||||
if (connection == null) return null;
|
if (connection == null) return null;
|
||||||
|
|
||||||
final int transactionId = nextTransactionId++;
|
final int transactionId = nextTransactionId++;
|
||||||
if (nextTransactionId > Integer.MAX_VALUE) nextTransactionId = 0; // ? Can and should I use negative numbers too?
|
|
||||||
connection.send(new RequestCommandCompletionsC2SPacket(transactionId, command));
|
connection.send(new RequestCommandCompletionsC2SPacket(transactionId, command));
|
||||||
|
|
||||||
final CompletableFuture<CommandSuggestionsS2CPacket> future = new CompletableFuture<>();
|
final CompletableFuture<CommandSuggestionsS2CPacket> future = new CompletableFuture<>();
|
||||||
|
@ -50,7 +46,7 @@ public class TabComplete extends Listener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void packetReceived (Packet packet) {
|
public void packetReceived (Packet<?> packet) {
|
||||||
if (packet instanceof CommandSuggestionsS2CPacket) packetReceived((CommandSuggestionsS2CPacket) packet);
|
if (packet instanceof CommandSuggestionsS2CPacket) packetReceived((CommandSuggestionsS2CPacket) packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ public class Instrument {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
this.sound = name;
|
this.sound = sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Instrument (int id, String name, int offset) {
|
private Instrument (int id, String name, int offset) {
|
||||||
|
|
|
@ -19,7 +19,7 @@ public class MidiConverter {
|
||||||
public static final int NOTE_OFF = 0x80;
|
public static final int NOTE_OFF = 0x80;
|
||||||
|
|
||||||
public static Song getSongFromUrl(URL url) throws IOException, InvalidMidiDataException, URISyntaxException, NoSuchAlgorithmException, KeyManagementException {
|
public static Song getSongFromUrl(URL url) throws IOException, InvalidMidiDataException, URISyntaxException, NoSuchAlgorithmException, KeyManagementException {
|
||||||
Sequence sequence = MidiSystem.getSequence(DownloadUtilities.DownloadToInputStream(url, 5*1024*1024));
|
Sequence sequence = MidiSystem.getSequence(DownloadUtilities.DownloadToInputStream(url));
|
||||||
return getSong(sequence, Paths.get(url.toURI().getPath()).getFileName().toString());
|
return getSong(sequence, Paths.get(url.toURI().getPath()).getFileName().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -164,7 +164,7 @@ public class NBSConverter {
|
||||||
if (index >= customInstruments.size()) continue;
|
if (index >= customInstruments.size()) continue;
|
||||||
NBSCustomInstrument customInstrument = customInstruments.get(index);
|
NBSCustomInstrument customInstrument = customInstruments.get(index);
|
||||||
instrument = Instrument.of(customInstrument.name);
|
instrument = Instrument.of(customInstrument.name);
|
||||||
// key += customInstrument.pitch;
|
key += customInstrument.pitch;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key < 33 || key > 57) {
|
if (key < 33 || key > 57) {
|
||||||
|
|
|
@ -17,7 +17,7 @@ public class SongLoaderThread extends Thread {
|
||||||
public SongLoaderException exception;
|
public SongLoaderException exception;
|
||||||
public Song song;
|
public Song song;
|
||||||
|
|
||||||
private boolean isUrl = false;
|
private boolean isUrl;
|
||||||
|
|
||||||
public SongLoaderThread (URL location) throws SongLoaderException {
|
public SongLoaderThread (URL location) throws SongLoaderException {
|
||||||
isUrl = true;
|
isUrl = true;
|
||||||
|
@ -34,7 +34,7 @@ public class SongLoaderThread extends Thread {
|
||||||
String name;
|
String name;
|
||||||
try {
|
try {
|
||||||
if (isUrl) {
|
if (isUrl) {
|
||||||
bytes = DownloadUtilities.DownloadToByteArray(songUrl, 10*1024*1024);
|
bytes = DownloadUtilities.DownloadToByteArray(songUrl);
|
||||||
name = Paths.get(songUrl.toURI().getPath()).getFileName().toString();
|
name = Paths.get(songUrl.toURI().getPath()).getFileName().toString();
|
||||||
} else {
|
} else {
|
||||||
bytes = Files.readAllBytes(songPath.toPath());
|
bytes = Files.readAllBytes(songPath.toPath());
|
||||||
|
|
|
@ -28,7 +28,7 @@ public class DownloadUtilities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] DownloadToByteArray(URL url, int maxSize) throws IOException, KeyManagementException, NoSuchAlgorithmException {
|
public static byte[] DownloadToByteArray(URL url) throws IOException, KeyManagementException, NoSuchAlgorithmException {
|
||||||
SSLContext ctx = SSLContext.getInstance("TLS");
|
SSLContext ctx = SSLContext.getInstance("TLS");
|
||||||
ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
|
ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
|
||||||
SSLContext.setDefault(ctx);
|
SSLContext.setDefault(ctx);
|
||||||
|
@ -41,13 +41,9 @@ public class DownloadUtilities {
|
||||||
ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
|
ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
|
||||||
byte[] buf = new byte[1024];
|
byte[] buf = new byte[1024];
|
||||||
int n;
|
int n;
|
||||||
int tot = 0;
|
|
||||||
while ((n = downloadStream.read(buf)) > 0) {
|
while ((n = downloadStream.read(buf)) > 0) {
|
||||||
byteArrayStream.write(buf, 0, n);
|
byteArrayStream.write(buf, 0, n);
|
||||||
tot += n;
|
|
||||||
if (tot > maxSize) {
|
|
||||||
throw new IOException("File is too large");
|
|
||||||
}
|
|
||||||
if (Thread.interrupted()) {
|
if (Thread.interrupted()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -57,7 +53,7 @@ public class DownloadUtilities {
|
||||||
// Closing a ByteArrayInputStream has no effect, so I do not close it.
|
// Closing a ByteArrayInputStream has no effect, so I do not close it.
|
||||||
}
|
}
|
||||||
|
|
||||||
public static InputStream DownloadToInputStream(URL url, int maxSize) throws KeyManagementException, NoSuchAlgorithmException, IOException {
|
public static InputStream DownloadToInputStream(URL url) throws KeyManagementException, NoSuchAlgorithmException, IOException {
|
||||||
return new ByteArrayInputStream(DownloadToByteArray(url, maxSize));
|
return new ByteArrayInputStream(DownloadToByteArray(url));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package land.chipmunk.chipmunkmod.util;
|
||||||
|
|
||||||
|
public class MathUtilities {
|
||||||
|
public static float clamp (float value, float min, float max) {
|
||||||
|
return Math.max(Math.min(value, max), min);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package land.chipmunk.chipmunkmod.util;
|
||||||
|
|
||||||
|
import com.mojang.brigadier.tree.CommandNode;
|
||||||
|
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||||
|
|
||||||
|
public class ServerUtilities {
|
||||||
|
public static boolean serverHasCommand (String name) {
|
||||||
|
final MinecraftClient client = MinecraftClient.getInstance();
|
||||||
|
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
||||||
|
|
||||||
|
if (networkHandler == null) return false;
|
||||||
|
|
||||||
|
for (CommandNode node : networkHandler.getCommandDispatcher().getRoot().getChildren()) {
|
||||||
|
if (!(node instanceof LiteralCommandNode literal)) continue;
|
||||||
|
|
||||||
|
if (literal.getLiteral().equals(name)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,380 +9,383 @@ import java.net.URL;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
// i am sure blackilykat did not write this - chayapak
|
||||||
|
// you are correct - blackilykat
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class used to execute Discord Webhooks with low effort
|
* Class used to execute Discord Webhooks with low effort
|
||||||
*/
|
*/
|
||||||
public class Webhook {
|
public class Webhook {
|
||||||
|
|
||||||
private final String url;
|
private final String url;
|
||||||
private String content;
|
private String content;
|
||||||
private String username;
|
private String username;
|
||||||
private String avatarUrl;
|
private String avatarUrl;
|
||||||
private boolean tts;
|
private boolean tts;
|
||||||
private List<EmbedObject> embeds = new ArrayList<>();
|
private List<EmbedObject> embeds = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new DiscordWebhook instance
|
* Constructs a new DiscordWebhook instance
|
||||||
*
|
*
|
||||||
* @param url The webhook URL obtained in Discord
|
* @param url The webhook URL obtained in Discord
|
||||||
*/
|
*/
|
||||||
public Webhook(String url) {
|
public Webhook(String url) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContent(String content) {
|
public void setContent(String content) {
|
||||||
this.content = content;
|
this.content = content;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUsername(String username) {
|
public void setUsername(String username) {
|
||||||
this.username = username;
|
this.username = username;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAvatarUrl(String avatarUrl) {
|
public void setAvatarUrl(String avatarUrl) {
|
||||||
this.avatarUrl = avatarUrl;
|
this.avatarUrl = avatarUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTts(boolean tts) {
|
public void setTts(boolean tts) {
|
||||||
this.tts = tts;
|
this.tts = tts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addEmbed(EmbedObject embed) {
|
public void addEmbed(EmbedObject embed) {
|
||||||
this.embeds.add(embed);
|
this.embeds.add(embed);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void execute() throws IOException {
|
public void execute() throws IOException {
|
||||||
if (this.content == null && this.embeds.isEmpty()) {
|
if (this.content == null && this.embeds.isEmpty()) {
|
||||||
throw new IllegalArgumentException("Set content or add at least one EmbedObject");
|
throw new IllegalArgumentException("Set content or add at least one EmbedObject");
|
||||||
}
|
}
|
||||||
|
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
|
|
||||||
json.put("content", this.content);
|
json.put("content", this.content);
|
||||||
json.put("username", this.username);
|
json.put("username", this.username);
|
||||||
json.put("avatar_url", this.avatarUrl);
|
json.put("avatar_url", this.avatarUrl);
|
||||||
json.put("tts", this.tts);
|
json.put("tts", this.tts);
|
||||||
|
|
||||||
if (!this.embeds.isEmpty()) {
|
if (!this.embeds.isEmpty()) {
|
||||||
List<JSONObject> embedObjects = new ArrayList<>();
|
List<JSONObject> embedObjects = new ArrayList<>();
|
||||||
|
|
||||||
for (EmbedObject embed : this.embeds) {
|
for (EmbedObject embed : this.embeds) {
|
||||||
JSONObject jsonEmbed = new JSONObject();
|
JSONObject jsonEmbed = new JSONObject();
|
||||||
|
|
||||||
jsonEmbed.put("title", embed.getTitle());
|
jsonEmbed.put("title", embed.getTitle());
|
||||||
jsonEmbed.put("description", embed.getDescription());
|
jsonEmbed.put("description", embed.getDescription());
|
||||||
jsonEmbed.put("url", embed.getUrl());
|
jsonEmbed.put("url", embed.getUrl());
|
||||||
|
|
||||||
if (embed.getColor() != null) {
|
if (embed.getColor() != null) {
|
||||||
Color color = embed.getColor();
|
Color color = embed.getColor();
|
||||||
int rgb = color.getRed();
|
int rgb = color.getRed();
|
||||||
rgb = (rgb << 8) + color.getGreen();
|
rgb = (rgb << 8) + color.getGreen();
|
||||||
rgb = (rgb << 8) + color.getBlue();
|
rgb = (rgb << 8) + color.getBlue();
|
||||||
|
|
||||||
jsonEmbed.put("color", rgb);
|
jsonEmbed.put("color", rgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
EmbedObject.Footer footer = embed.getFooter();
|
EmbedObject.Footer footer = embed.getFooter();
|
||||||
EmbedObject.Image image = embed.getImage();
|
EmbedObject.Image image = embed.getImage();
|
||||||
EmbedObject.Thumbnail thumbnail = embed.getThumbnail();
|
EmbedObject.Thumbnail thumbnail = embed.getThumbnail();
|
||||||
EmbedObject.Author author = embed.getAuthor();
|
EmbedObject.Author author = embed.getAuthor();
|
||||||
List<EmbedObject.Field> fields = embed.getFields();
|
List<EmbedObject.Field> fields = embed.getFields();
|
||||||
|
|
||||||
if (footer != null) {
|
if (footer != null) {
|
||||||
JSONObject jsonFooter = new JSONObject();
|
JSONObject jsonFooter = new JSONObject();
|
||||||
|
|
||||||
jsonFooter.put("text", footer.getText());
|
jsonFooter.put("text", footer.getText());
|
||||||
jsonFooter.put("icon_url", footer.getIconUrl());
|
jsonFooter.put("icon_url", footer.getIconUrl());
|
||||||
jsonEmbed.put("footer", jsonFooter);
|
jsonEmbed.put("footer", jsonFooter);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image != null) {
|
if (image != null) {
|
||||||
JSONObject jsonImage = new JSONObject();
|
JSONObject jsonImage = new JSONObject();
|
||||||
|
|
||||||
jsonImage.put("url", image.getUrl());
|
jsonImage.put("url", image.getUrl());
|
||||||
jsonEmbed.put("image", jsonImage);
|
jsonEmbed.put("image", jsonImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thumbnail != null) {
|
if (thumbnail != null) {
|
||||||
JSONObject jsonThumbnail = new JSONObject();
|
JSONObject jsonThumbnail = new JSONObject();
|
||||||
|
|
||||||
jsonThumbnail.put("url", thumbnail.getUrl());
|
jsonThumbnail.put("url", thumbnail.getUrl());
|
||||||
jsonEmbed.put("thumbnail", jsonThumbnail);
|
jsonEmbed.put("thumbnail", jsonThumbnail);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (author != null) {
|
if (author != null) {
|
||||||
JSONObject jsonAuthor = new JSONObject();
|
JSONObject jsonAuthor = new JSONObject();
|
||||||
|
|
||||||
jsonAuthor.put("name", author.getName());
|
jsonAuthor.put("name", author.getName());
|
||||||
jsonAuthor.put("url", author.getUrl());
|
jsonAuthor.put("url", author.getUrl());
|
||||||
jsonAuthor.put("icon_url", author.getIconUrl());
|
jsonAuthor.put("icon_url", author.getIconUrl());
|
||||||
jsonEmbed.put("author", jsonAuthor);
|
jsonEmbed.put("author", jsonAuthor);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<JSONObject> jsonFields = new ArrayList<>();
|
List<JSONObject> jsonFields = new ArrayList<>();
|
||||||
for (EmbedObject.Field field : fields) {
|
for (EmbedObject.Field field : fields) {
|
||||||
JSONObject jsonField = new JSONObject();
|
JSONObject jsonField = new JSONObject();
|
||||||
|
|
||||||
jsonField.put("name", field.getName());
|
jsonField.put("name", field.getName());
|
||||||
jsonField.put("value", field.getValue());
|
jsonField.put("value", field.getValue());
|
||||||
jsonField.put("inline", field.isInline());
|
jsonField.put("inline", field.isInline());
|
||||||
|
|
||||||
jsonFields.add(jsonField);
|
jsonFields.add(jsonField);
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonEmbed.put("fields", jsonFields.toArray());
|
jsonEmbed.put("fields", jsonFields.toArray());
|
||||||
embedObjects.add(jsonEmbed);
|
embedObjects.add(jsonEmbed);
|
||||||
}
|
}
|
||||||
|
|
||||||
json.put("embeds", embedObjects.toArray());
|
json.put("embeds", embedObjects.toArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
URL url = new URL(this.url);
|
URL url = new URL(this.url);
|
||||||
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
|
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
|
||||||
connection.addRequestProperty("Content-Type", "application/json");
|
connection.addRequestProperty("Content-Type", "application/json");
|
||||||
connection.addRequestProperty("User-Agent", "Java-DiscordWebhook-BY-Gelox_");
|
connection.addRequestProperty("User-Agent", "Java-DiscordWebhook-BY-Gelox_");
|
||||||
connection.setDoOutput(true);
|
connection.setDoOutput(true);
|
||||||
connection.setRequestMethod("POST");
|
connection.setRequestMethod("POST");
|
||||||
|
|
||||||
OutputStream stream = connection.getOutputStream();
|
OutputStream stream = connection.getOutputStream();
|
||||||
stream.write(json.toString().getBytes());
|
stream.write(json.toString().getBytes());
|
||||||
stream.flush();
|
stream.flush();
|
||||||
stream.close();
|
stream.close();
|
||||||
|
|
||||||
connection.getInputStream().close(); //I'm not sure why but it doesn't work without getting the InputStream
|
connection.getInputStream().close(); //I'm not sure why but it doesn't work without getting the InputStream
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class EmbedObject {
|
public static class EmbedObject {
|
||||||
private String title;
|
private String title;
|
||||||
private String description;
|
private String description;
|
||||||
private String url;
|
private String url;
|
||||||
private Color color;
|
private Color color;
|
||||||
|
|
||||||
private Footer footer;
|
private Footer footer;
|
||||||
private Thumbnail thumbnail;
|
private Thumbnail thumbnail;
|
||||||
private Image image;
|
private Image image;
|
||||||
private Author author;
|
private Author author;
|
||||||
private List<Field> fields = new ArrayList<>();
|
private List<Field> fields = new ArrayList<>();
|
||||||
|
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getUrl() {
|
public String getUrl() {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Color getColor() {
|
public Color getColor() {
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Footer getFooter() {
|
public Footer getFooter() {
|
||||||
return footer;
|
return footer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Thumbnail getThumbnail() {
|
public Thumbnail getThumbnail() {
|
||||||
return thumbnail;
|
return thumbnail;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Image getImage() {
|
public Image getImage() {
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Author getAuthor() {
|
public Author getAuthor() {
|
||||||
return author;
|
return author;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Field> getFields() {
|
public List<Field> getFields() {
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EmbedObject setTitle(String title) {
|
public EmbedObject setTitle(String title) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EmbedObject setDescription(String description) {
|
public EmbedObject setDescription(String description) {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EmbedObject setUrl(String url) {
|
public EmbedObject setUrl(String url) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EmbedObject setColor(Color color) {
|
public EmbedObject setColor(Color color) {
|
||||||
this.color = color;
|
this.color = color;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EmbedObject setFooter(String text, String icon) {
|
public EmbedObject setFooter(String text, String icon) {
|
||||||
this.footer = new Footer(text, icon);
|
this.footer = new Footer(text, icon);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EmbedObject setThumbnail(String url) {
|
public EmbedObject setThumbnail(String url) {
|
||||||
this.thumbnail = new Thumbnail(url);
|
this.thumbnail = new Thumbnail(url);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EmbedObject setImage(String url) {
|
public EmbedObject setImage(String url) {
|
||||||
this.image = new Image(url);
|
this.image = new Image(url);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EmbedObject setAuthor(String name, String url, String icon) {
|
public EmbedObject setAuthor(String name, String url, String icon) {
|
||||||
this.author = new Author(name, url, icon);
|
this.author = new Author(name, url, icon);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public EmbedObject addField(String name, String value, boolean inline) {
|
public EmbedObject addField(String name, String value, boolean inline) {
|
||||||
this.fields.add(new Field(name, value, inline));
|
this.fields.add(new Field(name, value, inline));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Footer {
|
private class Footer {
|
||||||
private String text;
|
private String text;
|
||||||
private String iconUrl;
|
private String iconUrl;
|
||||||
|
|
||||||
private Footer(String text, String iconUrl) {
|
private Footer(String text, String iconUrl) {
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.iconUrl = iconUrl;
|
this.iconUrl = iconUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getText() {
|
private String getText() {
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getIconUrl() {
|
private String getIconUrl() {
|
||||||
return iconUrl;
|
return iconUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Thumbnail {
|
private class Thumbnail {
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
private Thumbnail(String url) {
|
private Thumbnail(String url) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUrl() {
|
private String getUrl() {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Image {
|
private class Image {
|
||||||
private String url;
|
private String url;
|
||||||
|
|
||||||
private Image(String url) {
|
private Image(String url) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUrl() {
|
private String getUrl() {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Author {
|
private class Author {
|
||||||
private String name;
|
private String name;
|
||||||
private String url;
|
private String url;
|
||||||
private String iconUrl;
|
private String iconUrl;
|
||||||
|
|
||||||
private Author(String name, String url, String iconUrl) {
|
private Author(String name, String url, String iconUrl) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.iconUrl = iconUrl;
|
this.iconUrl = iconUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getName() {
|
private String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getUrl() {
|
private String getUrl() {
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getIconUrl() {
|
private String getIconUrl() {
|
||||||
return iconUrl;
|
return iconUrl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class Field {
|
private class Field {
|
||||||
private String name;
|
private String name;
|
||||||
private String value;
|
private String value;
|
||||||
private boolean inline;
|
private boolean inline;
|
||||||
|
|
||||||
private Field(String name, String value, boolean inline) {
|
private Field(String name, String value, boolean inline) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.inline = inline;
|
this.inline = inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getName() {
|
private String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getValue() {
|
private String getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isInline() {
|
private boolean isInline() {
|
||||||
return inline;
|
return inline;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class JSONObject {
|
private class JSONObject {
|
||||||
|
|
||||||
private final HashMap<String, Object> map = new HashMap<>();
|
private final HashMap<String, Object> map = new HashMap<>();
|
||||||
|
|
||||||
void put(String key, Object value) {
|
void put(String key, Object value) {
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
map.put(key, value);
|
map.put(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
Set<Map.Entry<String, Object>> entrySet = map.entrySet();
|
Set<Map.Entry<String, Object>> entrySet = map.entrySet();
|
||||||
builder.append("{");
|
builder.append("{");
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Map.Entry<String, Object> entry : entrySet) {
|
for (Map.Entry<String, Object> entry : entrySet) {
|
||||||
Object val = entry.getValue();
|
Object val = entry.getValue();
|
||||||
builder.append(quote(entry.getKey())).append(":");
|
builder.append(quote(entry.getKey())).append(":");
|
||||||
|
|
||||||
if (val instanceof String) {
|
if (val instanceof String) {
|
||||||
builder.append(quote(String.valueOf(val)));
|
builder.append(quote(String.valueOf(val)));
|
||||||
} else if (val instanceof Integer) {
|
} else if (val instanceof Integer) {
|
||||||
builder.append(Integer.valueOf(String.valueOf(val)));
|
builder.append(Integer.valueOf(String.valueOf(val)));
|
||||||
} else if (val instanceof Boolean) {
|
} else if (val instanceof Boolean) {
|
||||||
builder.append(val);
|
builder.append(val);
|
||||||
} else if (val instanceof JSONObject) {
|
} else if (val instanceof JSONObject) {
|
||||||
builder.append(val.toString());
|
builder.append(val.toString());
|
||||||
} else if (val.getClass().isArray()) {
|
} else if (val.getClass().isArray()) {
|
||||||
builder.append("[");
|
builder.append("[");
|
||||||
int len = Array.getLength(val);
|
int len = Array.getLength(val);
|
||||||
for (int j = 0; j < len; j++) {
|
for (int j = 0; j < len; j++) {
|
||||||
builder.append(Array.get(val, j).toString()).append(j != len - 1 ? "," : "");
|
builder.append(Array.get(val, j).toString()).append(j != len - 1 ? "," : "");
|
||||||
}
|
}
|
||||||
builder.append("]");
|
builder.append("]");
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.append(++i == entrySet.size() ? "}" : ",");
|
builder.append(++i == entrySet.size() ? "}" : ",");
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String quote(String string) {
|
private String quote(String string) {
|
||||||
return "\"" + string + "\"";
|
return "\"" + string + "\"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
"ClientPlayerEntityMixin",
|
"ClientPlayerEntityMixin",
|
||||||
"ClientPlayNetworkHandlerAccessor",
|
"ClientPlayNetworkHandlerAccessor",
|
||||||
"ClientPlayNetworkHandlerMixin",
|
"ClientPlayNetworkHandlerMixin",
|
||||||
|
"ClientPlayNetworkHandlerInvoker",
|
||||||
"DecoderHandlerMixin",
|
"DecoderHandlerMixin",
|
||||||
"ElderGuardianAppearanceParticleMixin",
|
"ElderGuardianAppearanceParticleMixin",
|
||||||
"KeyboardInputMixin",
|
"KeyboardInputMixin",
|
||||||
|
@ -21,7 +22,12 @@
|
||||||
"NbtIoMixin",
|
"NbtIoMixin",
|
||||||
"SessionMixin",
|
"SessionMixin",
|
||||||
"StringHelperMixin",
|
"StringHelperMixin",
|
||||||
"TitleScreenMixin"
|
"TitleScreenMixin",
|
||||||
|
"IdentifierMixin",
|
||||||
|
"DecoratedPotBlockEntitySherdsMixin",
|
||||||
|
"TextMixin",
|
||||||
|
"ClientConnectionInvoker",
|
||||||
|
"ClientConnectionAccessor"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|
|
@ -15,7 +15,8 @@
|
||||||
"sbot": { "prefix": ":", "key": null },
|
"sbot": { "prefix": ":", "key": null },
|
||||||
"chipmunk": { "prefix": "'", "key": null },
|
"chipmunk": { "prefix": "'", "key": null },
|
||||||
"chomens": { "prefix": "*", "key": null },
|
"chomens": { "prefix": "*", "key": null },
|
||||||
"kittycorp": { "prefix": "^", "key": null }
|
"kittycorp": { "prefix": "^", "key": null },
|
||||||
|
"testbot": { "prefix": "-", "webhookUrl": null }
|
||||||
},
|
},
|
||||||
|
|
||||||
"customChat": {
|
"customChat": {
|
Loading…
Reference in a new issue