forked from ChomeNS/chipmunkmod
Compare commits
26 commits
2d4e319c93
...
5a68eb0848
Author | SHA1 | Date | |
---|---|---|---|
5a68eb0848 | |||
1547326a54 | |||
3328fa4ff1 | |||
7afcc606fe | |||
02488b4289 | |||
9c99b9edcf | |||
535154a1a0 | |||
b86e6d649e | |||
99d37d33f9 | |||
a2b2de94f9 | |||
d286767f7a | |||
fd6dd2593b | |||
7e232a4115 | |||
b2d9d994fe | |||
3810b4e611 | |||
29ef3324fc | |||
e51eae558c | |||
7bf9886cb1 | |||
7206ef4629 | |||
3eac1f2c73 | |||
753c096308 | |||
2bcded3997 | |||
6a06c8589d | |||
b3dcef2232 | |||
2d60606de3 | |||
3530238408 |
32 changed files with 881 additions and 497 deletions
|
@ -1,9 +1,10 @@
|
|||
package land.chipmunk.chipmunkmod;
|
||||
|
||||
import com.google.gson.GsonBuilder;
|
||||
import land.chipmunk.chipmunkmod.testclient.modules.utility.AntiChatSpamModule;
|
||||
import land.chipmunk.chipmunkmod.util.Keybinds;
|
||||
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 net.fabricmc.api.ModInitializer;
|
||||
import java.io.InputStream;
|
||||
|
@ -14,6 +15,8 @@ import java.io.BufferedWriter;
|
|||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
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_FILE = new File(CONFIG_DIR, "chipmunkmod.json");
|
||||
|
||||
public static ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||
|
||||
@Override
|
||||
public void onInitialize () {
|
||||
// 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();
|
||||
TickRunnableHandler.registerTickEndRunnables();
|
||||
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 {
|
||||
|
|
|
@ -29,7 +29,13 @@ public class Configuration {
|
|||
public BotInfo chipmunk = new BotInfo("'", null);
|
||||
public BotInfo chomens = 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
|
||||
|
|
|
@ -24,6 +24,8 @@ import java.util.List;
|
|||
|
||||
import static com.mojang.brigadier.arguments.BoolArgumentType.bool;
|
||||
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.integer;
|
||||
import static com.mojang.brigadier.arguments.LongArgumentType.getLong;
|
||||
|
@ -58,10 +60,10 @@ public class MusicCommand {
|
|||
|
||||
.then(
|
||||
literal("list")
|
||||
.executes(c -> instance.list(c, root))
|
||||
.executes(c -> instance.list(root))
|
||||
.then(
|
||||
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)
|
||||
)
|
||||
)
|
||||
|
||||
.then(
|
||||
literal("useCore")
|
||||
.then(
|
||||
|
@ -88,6 +91,22 @@ public class MusicCommand {
|
|||
.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;
|
||||
}
|
||||
|
||||
public int list (CommandContext<FabricClientCommandSource> context, Path path) throws CommandSyntaxException {
|
||||
final FabricClientCommandSource source = context.getSource();
|
||||
|
||||
public int list (Path path) throws CommandSyntaxException {
|
||||
final CommandManager commandManager = CommandManager.INSTANCE;
|
||||
|
||||
final String prefix = commandManager.prefix;
|
||||
|
@ -279,4 +296,33 @@ public class MusicCommand {
|
|||
|
||||
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.context.CommandContext;
|
||||
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
||||
import land.chipmunk.chipmunkmod.modules.CommandCore;
|
||||
import land.chipmunk.chipmunkmod.modules.CustomChat;
|
||||
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
||||
import net.minecraft.text.Text;
|
||||
|
@ -27,6 +28,7 @@ public class ReloadConfigCommand {
|
|||
ChipmunkMod.CONFIG = ChipmunkMod.loadConfig();
|
||||
|
||||
CustomChat.INSTANCE.reloadFormat();
|
||||
CommandCore.INSTANCE.reloadRelativeArea();
|
||||
|
||||
source.sendFeedback(Text.literal("Successfully reloaded the config"));
|
||||
} catch (IOException e) {
|
||||
|
|
|
@ -20,7 +20,6 @@ import net.minecraft.client.util.Session;
|
|||
import net.minecraft.text.Text;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||
import java.util.Optional;
|
||||
import land.chipmunk.chipmunkmod.mixin.MinecraftClientAccessor;
|
||||
|
||||
public class UsernameCommand {
|
||||
|
|
|
@ -6,7 +6,7 @@ import net.minecraft.text.Text;
|
|||
public class Listener {
|
||||
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;
|
||||
|
||||
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
||||
import land.chipmunk.chipmunkmod.command.CommandManager;
|
||||
import land.chipmunk.chipmunkmod.modules.CustomChat;
|
||||
import land.chipmunk.chipmunkmod.util.SharedVariables;
|
||||
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.text.MutableText;
|
||||
import net.minecraft.text.Text;
|
||||
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.ModifyArg;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import land.chipmunk.chipmunkmod.command.CommandManager;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Mixin(net.minecraft.client.gui.screen.ChatScreen.class)
|
||||
public class ChatScreenMixin {
|
||||
public class ChatScreenMixin extends Screen {
|
||||
@Shadow protected TextFieldWidget chatField;
|
||||
@Shadow private String originalChatText;
|
||||
@Shadow ChatInputSuggestor chatInputSuggestor;
|
||||
@Shadow private int messageHistorySize = -1;
|
||||
|
||||
@Inject(at = @At("HEAD"), method = "sendMessage", cancellable = true)
|
||||
public void sendMessage(String chatText, boolean addToHistory, CallbackInfoReturnable<Boolean> cir) {
|
||||
|
@ -37,6 +43,19 @@ public class ChatScreenMixin {
|
|||
}
|
||||
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)) {
|
||||
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 void init (CallbackInfo ci) {
|
||||
chatField.setMaxLength(Integer.MAX_VALUE);
|
||||
public ChatScreenMixin(String originalChatText) {
|
||||
super(Text.translatable("chat_screen.title"));
|
||||
this.originalChatText = originalChatText;
|
||||
}
|
||||
|
||||
@ModifyArg(method = "normalize", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/StringHelper;truncateChat(Ljava/lang/String;)Ljava/lang/String;"))
|
||||
private String normalize (String text) {
|
||||
return text;
|
||||
@Inject(at = @At("TAIL"), method = "init", cancellable = true)
|
||||
public void init (CallbackInfo ci) {
|
||||
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.c2s.play.RequestCommandCompletionsC2SPacket;
|
||||
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.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.CallbackInfo;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@Mixin(net.minecraft.network.ClientConnection.class)
|
||||
|
@ -39,6 +45,10 @@ public class ClientConnectionMixin {
|
|||
|
||||
@Inject(method = "handlePacket", at = @At("HEAD"), cancellable = true)
|
||||
private static void handlePacket (Packet<?> packet, PacketListener _listener, CallbackInfo ci) {
|
||||
for (Listener listener : ListenerManager.listeners) {
|
||||
listener.packetReceived(packet);
|
||||
}
|
||||
|
||||
// please don't skid this.,.
|
||||
// mabe mabe mabe
|
||||
// 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!");
|
||||
ci.cancel();
|
||||
}
|
||||
}
|
||||
} else if (packet instanceof PlaySoundS2CPacket t_packet) {
|
||||
if (t_packet.getVolume() != 1) return;
|
||||
|
||||
for (Listener listener : ListenerManager.listeners) {
|
||||
listener.packetReceived(packet);
|
||||
final Optional<RegistryKey<SoundEvent>> event = t_packet.getSound().getKey();
|
||||
|
||||
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;
|
||||
|
||||
import net.minecraft.client.network.PlayerListEntry;
|
||||
import net.minecraft.network.ClientConnection;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
@Mixin(net.minecraft.client.network.ClientPlayNetworkHandler.class)
|
||||
public interface ClientPlayNetworkHandlerAccessor {
|
||||
@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;
|
||||
|
||||
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
||||
import land.chipmunk.chipmunkmod.command.CommandManager;
|
||||
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.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import net.minecraft.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)
|
||||
public class ClientPlayNetworkHandlerMixin {
|
||||
|
@ -23,6 +24,7 @@ public class ClientPlayNetworkHandlerMixin {
|
|||
private void onGameJoin (GameJoinS2CPacket packet, CallbackInfo ci) {
|
||||
final CommandRegistryAccess commandRegistryAccess = CommandRegistryAccess.of(this.combinedDynamicRegistries.getCombinedRegistryManager(), this.enabledFeatures);
|
||||
|
||||
KaboomCheck.INSTANCE.onJoin();
|
||||
CommandManager.INSTANCE = new CommandManager(ChipmunkMod.CONFIG.commands.prefix, commandRegistryAccess);
|
||||
SelfCare.INSTANCE.init();
|
||||
LoopCrouch.INSTANCE.init();
|
||||
|
@ -30,8 +32,8 @@ public class ClientPlayNetworkHandlerMixin {
|
|||
RainbowName.INSTANCE.init();
|
||||
}
|
||||
|
||||
@Inject(method = "onGameJoin", at = @At("HEAD"))
|
||||
private void onGameJoinHead (GameJoinS2CPacket packet, CallbackInfo ci) {
|
||||
Players.INSTANCE.init();
|
||||
@Inject(method = "onPlayerRemove", at = @At("HEAD"), cancellable = true)
|
||||
private void onPlayerRemove (PlayerRemoveS2CPacket packet, CallbackInfo ci) {
|
||||
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;
|
||||
@Getter @Setter private boolean ready = false;
|
||||
@Getter @Setter private BlockPos origin;
|
||||
@Getter private final BlockArea relativeArea;
|
||||
@Getter private BlockArea relativeArea;
|
||||
@Getter @Setter private BlockPos currentBlockRelative;
|
||||
|
||||
public static CommandCore INSTANCE = new CommandCore(MinecraftClient.getInstance(), ChipmunkMod.CONFIG.core.relativeArea);
|
||||
|
@ -30,6 +30,10 @@ public class CommandCore {
|
|||
this.relativeArea = relativeArea;
|
||||
}
|
||||
|
||||
public void reloadRelativeArea () {
|
||||
relativeArea = ChipmunkMod.CONFIG.core.relativeArea;
|
||||
}
|
||||
|
||||
public void move (Vec3d position) {
|
||||
if (!ready) {
|
||||
ready = true;
|
||||
|
@ -52,7 +56,9 @@ public class CommandCore {
|
|||
final BlockPos relEnd = relativeArea.end();
|
||||
|
||||
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.getY() + origin.getY(),
|
||||
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.suggestion.Suggestion;
|
||||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
||||
import land.chipmunk.chipmunkmod.data.MutablePlayerListEntry;
|
||||
import land.chipmunk.chipmunkmod.listeners.Listener;
|
||||
import land.chipmunk.chipmunkmod.listeners.ListenerManager;
|
||||
import land.chipmunk.chipmunkmod.mixin.ClientPlayNetworkHandlerAccessor;
|
||||
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.s2c.play.CommandSuggestionsS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.PlayerListS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.PlayerRemoveS2CPacket;
|
||||
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 static land.chipmunk.chipmunkmod.util.ServerUtilities.serverHasCommand;
|
||||
|
||||
public class Players extends Listener {
|
||||
public List<MutablePlayerListEntry> list = new ArrayList<>();
|
||||
|
||||
public static Players INSTANCE = new Players(MinecraftClient.getInstance());
|
||||
|
||||
private Timer timer;
|
||||
|
||||
private final MinecraftClient client;
|
||||
|
||||
public Players (MinecraftClient client) {
|
||||
|
@ -33,37 +37,10 @@ public class Players extends Listener {
|
|||
TabComplete.INSTANCE.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();
|
||||
}
|
||||
public void init () {}
|
||||
|
||||
@Override
|
||||
public void packetReceived (Packet packet) {
|
||||
public void packetReceived (Packet<?> packet) {
|
||||
if (packet instanceof PlayerListS2CPacket) packetReceived((PlayerListS2CPacket) packet);
|
||||
else if (packet instanceof PlayerRemoveS2CPacket) packetReceived((PlayerRemoveS2CPacket) packet);
|
||||
}
|
||||
|
@ -136,7 +113,10 @@ public class Players extends Listener {
|
|||
private void addPlayer (PlayerListS2CPacket.Entry newEntry) {
|
||||
try {
|
||||
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));
|
||||
} catch (Exception e) {
|
||||
|
@ -174,6 +154,12 @@ public class Players extends Listener {
|
|||
final MutablePlayerListEntry target = getEntry(uuid);
|
||||
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 ");
|
||||
|
||||
if (future == null) return;
|
||||
|
@ -187,14 +173,33 @@ public class Players extends Listener {
|
|||
|
||||
final Message tooltip = suggestion.getTooltip();
|
||||
if (tooltip != null || !suggestion.getText().equals(username)) continue;
|
||||
|
||||
return packet;
|
||||
}
|
||||
|
||||
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;
|
||||
});
|
||||
} catch (Exception e) {
|
||||
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();
|
||||
|
||||
timer = new Timer();
|
||||
timer.schedule(task, 0, 75);
|
||||
timer.schedule(task, 0, 50);
|
||||
}
|
||||
|
||||
private String[] generateColorCodes(int length) {
|
||||
|
|
|
@ -7,14 +7,14 @@ import lombok.Setter;
|
|||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import com.mojang.brigadier.tree.CommandNode;
|
||||
import com.mojang.brigadier.tree.LiteralCommandNode;
|
||||
import lombok.Getter;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import static land.chipmunk.chipmunkmod.util.ServerUtilities.serverHasCommand;
|
||||
|
||||
public class SelfCare extends Listener {
|
||||
private final MinecraftClient client;
|
||||
@Getter private final long interval;
|
||||
|
@ -114,19 +114,4 @@ public class SelfCare extends Listener {
|
|||
if (!cspy && cspyEnabled) { if (serverHasCommand("c")) networkHandler.sendChatCommand("c on"); }
|
||||
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;
|
||||
|
||||
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.Song;
|
||||
import land.chipmunk.chipmunkmod.song.SongLoaderException;
|
||||
import land.chipmunk.chipmunkmod.song.SongLoaderThread;
|
||||
import land.chipmunk.chipmunkmod.util.MathUtilities;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
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.network.ClientPlayNetworkHandler;
|
||||
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.SoundEvent;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
@ -42,6 +49,9 @@ public class SongPlayer {
|
|||
private int ticksUntilPausedActionbar = 20;
|
||||
|
||||
@Getter @Setter private boolean useCore = true;
|
||||
@Getter @Setter private boolean actionbar = true;
|
||||
|
||||
@Getter @Setter private float pitch = 0;
|
||||
|
||||
private final MinecraftClient client;
|
||||
|
||||
|
@ -120,8 +130,8 @@ public class SongPlayer {
|
|||
else ticksUntilPausedActionbar = 20;
|
||||
|
||||
try {
|
||||
if (!useCore) client.player.sendActionBar(generateActionbar());
|
||||
else CommandCore.INSTANCE.run("title " + SELECTOR + " actionbar " + GsonComponentSerializer.gson().serialize(generateActionbar()));
|
||||
if (!useCore && actionbar) client.player.sendActionBar(generateActionbar());
|
||||
else if (actionbar) CommandCore.INSTANCE.run("title " + SELECTOR + " actionbar " + GsonComponentSerializer.gson().serialize(generateActionbar()));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -137,7 +147,7 @@ public class SongPlayer {
|
|||
}
|
||||
};
|
||||
|
||||
playTimer.schedule(playTask, 50, 50);
|
||||
playTimer.schedule(playTask, 60, 50);
|
||||
|
||||
if (currentSong != null) currentSong.play();
|
||||
}
|
||||
|
@ -150,7 +160,7 @@ public class SongPlayer {
|
|||
.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(" | ", 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("%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;
|
||||
}
|
||||
|
||||
public Component formatTime (long millis) {
|
||||
public Text formatTime (long millis) {
|
||||
final int seconds = (int) millis / 1000;
|
||||
|
||||
final String minutePart = String.valueOf(seconds / 60);
|
||||
final String unpaddedSecondPart = String.valueOf(seconds % 60);
|
||||
|
||||
return Component.translatable(
|
||||
return Text.translatable(
|
||||
"%s:%s",
|
||||
Component.text(minutePart),
|
||||
Component.text(unpaddedSecondPart.length() < 2 ? "0" + unpaddedSecondPart : unpaddedSecondPart)
|
||||
Text.literal(minutePart),
|
||||
Text.literal(unpaddedSecondPart.length() < 2 ? "0" + unpaddedSecondPart : unpaddedSecondPart)
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -204,18 +214,34 @@ public class SongPlayer {
|
|||
while (currentSong.reachedNextNote()) {
|
||||
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 {
|
||||
if (!useCore) {
|
||||
if (floatingPitch < 0 || floatingPitch > 2) return;
|
||||
|
||||
if (!useCore && client.player != null) {
|
||||
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
|
||||
|
||||
client.player.playSound(SoundEvent.of(Identifier.of(thing[0], thing[1])), SoundCategory.RECORDS, note.volume, floatingPitch);
|
||||
} else CommandCore.INSTANCE.run("execute as " + SELECTOR + " at @s run playsound " + note.instrument.sound + " record @s ~ ~ ~ " + note.volume + " " + floatingPitch);
|
||||
final ClientPlayNetworkHandlerAccessor networkHandlerAccessor = (ClientPlayNetworkHandlerAccessor) client.getNetworkHandler();
|
||||
|
||||
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) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ 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.ClientConnection;
|
||||
|
@ -22,8 +21,6 @@ public class TabComplete extends Listener {
|
|||
|
||||
public static TabComplete INSTANCE = new TabComplete(MinecraftClient.getInstance());
|
||||
|
||||
@Getter private boolean loggedIn = false;
|
||||
|
||||
public TabComplete (MinecraftClient client) {
|
||||
this.client = client;
|
||||
ListenerManager.addListener(this);
|
||||
|
@ -41,7 +38,6 @@ public class TabComplete extends Listener {
|
|||
if (connection == null) return null;
|
||||
|
||||
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));
|
||||
|
||||
final CompletableFuture<CommandSuggestionsS2CPacket> future = new CompletableFuture<>();
|
||||
|
@ -50,7 +46,7 @@ public class TabComplete extends Listener {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void packetReceived (Packet packet) {
|
||||
public void packetReceived (Packet<?> packet) {
|
||||
if (packet instanceof CommandSuggestionsS2CPacket) packetReceived((CommandSuggestionsS2CPacket) packet);
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ public class Instrument {
|
|||
this.id = id;
|
||||
this.name = name;
|
||||
this.offset = offset;
|
||||
this.sound = name;
|
||||
this.sound = sound;
|
||||
}
|
||||
|
||||
private Instrument (int id, String name, int offset) {
|
||||
|
|
|
@ -19,7 +19,7 @@ public class MidiConverter {
|
|||
public static final int NOTE_OFF = 0x80;
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ public class NBSConverter {
|
|||
if (index >= customInstruments.size()) continue;
|
||||
NBSCustomInstrument customInstrument = customInstruments.get(index);
|
||||
instrument = Instrument.of(customInstrument.name);
|
||||
// key += customInstrument.pitch;
|
||||
key += customInstrument.pitch;
|
||||
}
|
||||
|
||||
if (key < 33 || key > 57) {
|
||||
|
|
|
@ -17,7 +17,7 @@ public class SongLoaderThread extends Thread {
|
|||
public SongLoaderException exception;
|
||||
public Song song;
|
||||
|
||||
private boolean isUrl = false;
|
||||
private boolean isUrl;
|
||||
|
||||
public SongLoaderThread (URL location) throws SongLoaderException {
|
||||
isUrl = true;
|
||||
|
@ -34,7 +34,7 @@ public class SongLoaderThread extends Thread {
|
|||
String name;
|
||||
try {
|
||||
if (isUrl) {
|
||||
bytes = DownloadUtilities.DownloadToByteArray(songUrl, 10*1024*1024);
|
||||
bytes = DownloadUtilities.DownloadToByteArray(songUrl);
|
||||
name = Paths.get(songUrl.toURI().getPath()).getFileName().toString();
|
||||
} else {
|
||||
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");
|
||||
ctx.init(new KeyManager[0], new TrustManager[] {new DefaultTrustManager()}, new SecureRandom());
|
||||
SSLContext.setDefault(ctx);
|
||||
|
@ -41,13 +41,9 @@ public class DownloadUtilities {
|
|||
ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
|
||||
byte[] buf = new byte[1024];
|
||||
int n;
|
||||
int tot = 0;
|
||||
while ((n = downloadStream.read(buf)) > 0) {
|
||||
byteArrayStream.write(buf, 0, n);
|
||||
tot += n;
|
||||
if (tot > maxSize) {
|
||||
throw new IOException("File is too large");
|
||||
}
|
||||
|
||||
if (Thread.interrupted()) {
|
||||
return null;
|
||||
}
|
||||
|
@ -57,7 +53,7 @@ public class DownloadUtilities {
|
|||
// Closing a ByteArrayInputStream has no effect, so I do not close it.
|
||||
}
|
||||
|
||||
public static InputStream DownloadToInputStream(URL url, int maxSize) throws KeyManagementException, NoSuchAlgorithmException, IOException {
|
||||
return new ByteArrayInputStream(DownloadToByteArray(url, maxSize));
|
||||
public static InputStream DownloadToInputStream(URL url) throws KeyManagementException, NoSuchAlgorithmException, IOException {
|
||||
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.*;
|
||||
|
||||
// i am sure blackilykat did not write this - chayapak
|
||||
// you are correct - blackilykat
|
||||
|
||||
/**
|
||||
* Class used to execute Discord Webhooks with low effort
|
||||
*/
|
||||
public class Webhook {
|
||||
|
||||
private final String url;
|
||||
private String content;
|
||||
private String username;
|
||||
private String avatarUrl;
|
||||
private boolean tts;
|
||||
private List<EmbedObject> embeds = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructs a new DiscordWebhook instance
|
||||
*
|
||||
* @param url The webhook URL obtained in Discord
|
||||
*/
|
||||
public Webhook(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public void setAvatarUrl(String avatarUrl) {
|
||||
this.avatarUrl = avatarUrl;
|
||||
}
|
||||
|
||||
public void setTts(boolean tts) {
|
||||
this.tts = tts;
|
||||
}
|
||||
|
||||
public void addEmbed(EmbedObject embed) {
|
||||
this.embeds.add(embed);
|
||||
}
|
||||
|
||||
public void execute() throws IOException {
|
||||
if (this.content == null && this.embeds.isEmpty()) {
|
||||
throw new IllegalArgumentException("Set content or add at least one EmbedObject");
|
||||
}
|
||||
|
||||
JSONObject json = new JSONObject();
|
||||
|
||||
json.put("content", this.content);
|
||||
json.put("username", this.username);
|
||||
json.put("avatar_url", this.avatarUrl);
|
||||
json.put("tts", this.tts);
|
||||
|
||||
if (!this.embeds.isEmpty()) {
|
||||
List<JSONObject> embedObjects = new ArrayList<>();
|
||||
|
||||
for (EmbedObject embed : this.embeds) {
|
||||
JSONObject jsonEmbed = new JSONObject();
|
||||
|
||||
jsonEmbed.put("title", embed.getTitle());
|
||||
jsonEmbed.put("description", embed.getDescription());
|
||||
jsonEmbed.put("url", embed.getUrl());
|
||||
|
||||
if (embed.getColor() != null) {
|
||||
Color color = embed.getColor();
|
||||
int rgb = color.getRed();
|
||||
rgb = (rgb << 8) + color.getGreen();
|
||||
rgb = (rgb << 8) + color.getBlue();
|
||||
|
||||
jsonEmbed.put("color", rgb);
|
||||
}
|
||||
|
||||
EmbedObject.Footer footer = embed.getFooter();
|
||||
EmbedObject.Image image = embed.getImage();
|
||||
EmbedObject.Thumbnail thumbnail = embed.getThumbnail();
|
||||
EmbedObject.Author author = embed.getAuthor();
|
||||
List<EmbedObject.Field> fields = embed.getFields();
|
||||
|
||||
if (footer != null) {
|
||||
JSONObject jsonFooter = new JSONObject();
|
||||
|
||||
jsonFooter.put("text", footer.getText());
|
||||
jsonFooter.put("icon_url", footer.getIconUrl());
|
||||
jsonEmbed.put("footer", jsonFooter);
|
||||
}
|
||||
|
||||
if (image != null) {
|
||||
JSONObject jsonImage = new JSONObject();
|
||||
|
||||
jsonImage.put("url", image.getUrl());
|
||||
jsonEmbed.put("image", jsonImage);
|
||||
}
|
||||
|
||||
if (thumbnail != null) {
|
||||
JSONObject jsonThumbnail = new JSONObject();
|
||||
|
||||
jsonThumbnail.put("url", thumbnail.getUrl());
|
||||
jsonEmbed.put("thumbnail", jsonThumbnail);
|
||||
}
|
||||
|
||||
if (author != null) {
|
||||
JSONObject jsonAuthor = new JSONObject();
|
||||
|
||||
jsonAuthor.put("name", author.getName());
|
||||
jsonAuthor.put("url", author.getUrl());
|
||||
jsonAuthor.put("icon_url", author.getIconUrl());
|
||||
jsonEmbed.put("author", jsonAuthor);
|
||||
}
|
||||
|
||||
List<JSONObject> jsonFields = new ArrayList<>();
|
||||
for (EmbedObject.Field field : fields) {
|
||||
JSONObject jsonField = new JSONObject();
|
||||
|
||||
jsonField.put("name", field.getName());
|
||||
jsonField.put("value", field.getValue());
|
||||
jsonField.put("inline", field.isInline());
|
||||
|
||||
jsonFields.add(jsonField);
|
||||
}
|
||||
|
||||
jsonEmbed.put("fields", jsonFields.toArray());
|
||||
embedObjects.add(jsonEmbed);
|
||||
}
|
||||
|
||||
json.put("embeds", embedObjects.toArray());
|
||||
}
|
||||
|
||||
URL url = new URL(this.url);
|
||||
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
|
||||
connection.addRequestProperty("Content-Type", "application/json");
|
||||
connection.addRequestProperty("User-Agent", "Java-DiscordWebhook-BY-Gelox_");
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestMethod("POST");
|
||||
|
||||
OutputStream stream = connection.getOutputStream();
|
||||
stream.write(json.toString().getBytes());
|
||||
stream.flush();
|
||||
stream.close();
|
||||
|
||||
connection.getInputStream().close(); //I'm not sure why but it doesn't work without getting the InputStream
|
||||
connection.disconnect();
|
||||
}
|
||||
|
||||
public static class EmbedObject {
|
||||
private String title;
|
||||
private String description;
|
||||
private String url;
|
||||
private Color color;
|
||||
|
||||
private Footer footer;
|
||||
private Thumbnail thumbnail;
|
||||
private Image image;
|
||||
private Author author;
|
||||
private List<Field> fields = new ArrayList<>();
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public Footer getFooter() {
|
||||
return footer;
|
||||
}
|
||||
|
||||
public Thumbnail getThumbnail() {
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
public Image getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
public Author getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public List<Field> getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public EmbedObject setTitle(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedObject setDescription(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedObject setUrl(String url) {
|
||||
this.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedObject setColor(Color color) {
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedObject setFooter(String text, String icon) {
|
||||
this.footer = new Footer(text, icon);
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedObject setThumbnail(String url) {
|
||||
this.thumbnail = new Thumbnail(url);
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedObject setImage(String url) {
|
||||
this.image = new Image(url);
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedObject setAuthor(String name, String url, String icon) {
|
||||
this.author = new Author(name, url, icon);
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedObject addField(String name, String value, boolean inline) {
|
||||
this.fields.add(new Field(name, value, inline));
|
||||
return this;
|
||||
}
|
||||
|
||||
private class Footer {
|
||||
private String text;
|
||||
private String iconUrl;
|
||||
|
||||
private Footer(String text, String iconUrl) {
|
||||
this.text = text;
|
||||
this.iconUrl = iconUrl;
|
||||
}
|
||||
|
||||
private String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
private String getIconUrl() {
|
||||
return iconUrl;
|
||||
}
|
||||
}
|
||||
|
||||
private class Thumbnail {
|
||||
private String url;
|
||||
|
||||
private Thumbnail(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
private String getUrl() {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
private class Image {
|
||||
private String url;
|
||||
|
||||
private Image(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
private String getUrl() {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
private class Author {
|
||||
private String name;
|
||||
private String url;
|
||||
private String iconUrl;
|
||||
|
||||
private Author(String name, String url, String iconUrl) {
|
||||
this.name = name;
|
||||
this.url = url;
|
||||
this.iconUrl = iconUrl;
|
||||
}
|
||||
|
||||
private String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
private String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
private String getIconUrl() {
|
||||
return iconUrl;
|
||||
}
|
||||
}
|
||||
|
||||
private class Field {
|
||||
private String name;
|
||||
private String value;
|
||||
private boolean inline;
|
||||
|
||||
private Field(String name, String value, boolean inline) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.inline = inline;
|
||||
}
|
||||
|
||||
private String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
private String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
private boolean isInline() {
|
||||
return inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class JSONObject {
|
||||
|
||||
private final HashMap<String, Object> map = new HashMap<>();
|
||||
|
||||
void put(String key, Object value) {
|
||||
if (value != null) {
|
||||
map.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Set<Map.Entry<String, Object>> entrySet = map.entrySet();
|
||||
builder.append("{");
|
||||
|
||||
int i = 0;
|
||||
for (Map.Entry<String, Object> entry : entrySet) {
|
||||
Object val = entry.getValue();
|
||||
builder.append(quote(entry.getKey())).append(":");
|
||||
|
||||
if (val instanceof String) {
|
||||
builder.append(quote(String.valueOf(val)));
|
||||
} else if (val instanceof Integer) {
|
||||
builder.append(Integer.valueOf(String.valueOf(val)));
|
||||
} else if (val instanceof Boolean) {
|
||||
builder.append(val);
|
||||
} else if (val instanceof JSONObject) {
|
||||
builder.append(val.toString());
|
||||
} else if (val.getClass().isArray()) {
|
||||
builder.append("[");
|
||||
int len = Array.getLength(val);
|
||||
for (int j = 0; j < len; j++) {
|
||||
builder.append(Array.get(val, j).toString()).append(j != len - 1 ? "," : "");
|
||||
}
|
||||
builder.append("]");
|
||||
}
|
||||
|
||||
builder.append(++i == entrySet.size() ? "}" : ",");
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private String quote(String string) {
|
||||
return "\"" + string + "\"";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private final String url;
|
||||
private String content;
|
||||
private String username;
|
||||
private String avatarUrl;
|
||||
private boolean tts;
|
||||
private List<EmbedObject> embeds = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructs a new DiscordWebhook instance
|
||||
*
|
||||
* @param url The webhook URL obtained in Discord
|
||||
*/
|
||||
public Webhook(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public void setContent(String content) {
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public void setAvatarUrl(String avatarUrl) {
|
||||
this.avatarUrl = avatarUrl;
|
||||
}
|
||||
|
||||
public void setTts(boolean tts) {
|
||||
this.tts = tts;
|
||||
}
|
||||
|
||||
public void addEmbed(EmbedObject embed) {
|
||||
this.embeds.add(embed);
|
||||
}
|
||||
|
||||
public void execute() throws IOException {
|
||||
if (this.content == null && this.embeds.isEmpty()) {
|
||||
throw new IllegalArgumentException("Set content or add at least one EmbedObject");
|
||||
}
|
||||
|
||||
JSONObject json = new JSONObject();
|
||||
|
||||
json.put("content", this.content);
|
||||
json.put("username", this.username);
|
||||
json.put("avatar_url", this.avatarUrl);
|
||||
json.put("tts", this.tts);
|
||||
|
||||
if (!this.embeds.isEmpty()) {
|
||||
List<JSONObject> embedObjects = new ArrayList<>();
|
||||
|
||||
for (EmbedObject embed : this.embeds) {
|
||||
JSONObject jsonEmbed = new JSONObject();
|
||||
|
||||
jsonEmbed.put("title", embed.getTitle());
|
||||
jsonEmbed.put("description", embed.getDescription());
|
||||
jsonEmbed.put("url", embed.getUrl());
|
||||
|
||||
if (embed.getColor() != null) {
|
||||
Color color = embed.getColor();
|
||||
int rgb = color.getRed();
|
||||
rgb = (rgb << 8) + color.getGreen();
|
||||
rgb = (rgb << 8) + color.getBlue();
|
||||
|
||||
jsonEmbed.put("color", rgb);
|
||||
}
|
||||
|
||||
EmbedObject.Footer footer = embed.getFooter();
|
||||
EmbedObject.Image image = embed.getImage();
|
||||
EmbedObject.Thumbnail thumbnail = embed.getThumbnail();
|
||||
EmbedObject.Author author = embed.getAuthor();
|
||||
List<EmbedObject.Field> fields = embed.getFields();
|
||||
|
||||
if (footer != null) {
|
||||
JSONObject jsonFooter = new JSONObject();
|
||||
|
||||
jsonFooter.put("text", footer.getText());
|
||||
jsonFooter.put("icon_url", footer.getIconUrl());
|
||||
jsonEmbed.put("footer", jsonFooter);
|
||||
}
|
||||
|
||||
if (image != null) {
|
||||
JSONObject jsonImage = new JSONObject();
|
||||
|
||||
jsonImage.put("url", image.getUrl());
|
||||
jsonEmbed.put("image", jsonImage);
|
||||
}
|
||||
|
||||
if (thumbnail != null) {
|
||||
JSONObject jsonThumbnail = new JSONObject();
|
||||
|
||||
jsonThumbnail.put("url", thumbnail.getUrl());
|
||||
jsonEmbed.put("thumbnail", jsonThumbnail);
|
||||
}
|
||||
|
||||
if (author != null) {
|
||||
JSONObject jsonAuthor = new JSONObject();
|
||||
|
||||
jsonAuthor.put("name", author.getName());
|
||||
jsonAuthor.put("url", author.getUrl());
|
||||
jsonAuthor.put("icon_url", author.getIconUrl());
|
||||
jsonEmbed.put("author", jsonAuthor);
|
||||
}
|
||||
|
||||
List<JSONObject> jsonFields = new ArrayList<>();
|
||||
for (EmbedObject.Field field : fields) {
|
||||
JSONObject jsonField = new JSONObject();
|
||||
|
||||
jsonField.put("name", field.getName());
|
||||
jsonField.put("value", field.getValue());
|
||||
jsonField.put("inline", field.isInline());
|
||||
|
||||
jsonFields.add(jsonField);
|
||||
}
|
||||
|
||||
jsonEmbed.put("fields", jsonFields.toArray());
|
||||
embedObjects.add(jsonEmbed);
|
||||
}
|
||||
|
||||
json.put("embeds", embedObjects.toArray());
|
||||
}
|
||||
|
||||
URL url = new URL(this.url);
|
||||
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
|
||||
connection.addRequestProperty("Content-Type", "application/json");
|
||||
connection.addRequestProperty("User-Agent", "Java-DiscordWebhook-BY-Gelox_");
|
||||
connection.setDoOutput(true);
|
||||
connection.setRequestMethod("POST");
|
||||
|
||||
OutputStream stream = connection.getOutputStream();
|
||||
stream.write(json.toString().getBytes());
|
||||
stream.flush();
|
||||
stream.close();
|
||||
|
||||
connection.getInputStream().close(); //I'm not sure why but it doesn't work without getting the InputStream
|
||||
connection.disconnect();
|
||||
}
|
||||
|
||||
public static class EmbedObject {
|
||||
private String title;
|
||||
private String description;
|
||||
private String url;
|
||||
private Color color;
|
||||
|
||||
private Footer footer;
|
||||
private Thumbnail thumbnail;
|
||||
private Image image;
|
||||
private Author author;
|
||||
private List<Field> fields = new ArrayList<>();
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public Footer getFooter() {
|
||||
return footer;
|
||||
}
|
||||
|
||||
public Thumbnail getThumbnail() {
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
public Image getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
public Author getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
public List<Field> getFields() {
|
||||
return fields;
|
||||
}
|
||||
|
||||
public EmbedObject setTitle(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedObject setDescription(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedObject setUrl(String url) {
|
||||
this.url = url;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedObject setColor(Color color) {
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedObject setFooter(String text, String icon) {
|
||||
this.footer = new Footer(text, icon);
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedObject setThumbnail(String url) {
|
||||
this.thumbnail = new Thumbnail(url);
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedObject setImage(String url) {
|
||||
this.image = new Image(url);
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedObject setAuthor(String name, String url, String icon) {
|
||||
this.author = new Author(name, url, icon);
|
||||
return this;
|
||||
}
|
||||
|
||||
public EmbedObject addField(String name, String value, boolean inline) {
|
||||
this.fields.add(new Field(name, value, inline));
|
||||
return this;
|
||||
}
|
||||
|
||||
private class Footer {
|
||||
private String text;
|
||||
private String iconUrl;
|
||||
|
||||
private Footer(String text, String iconUrl) {
|
||||
this.text = text;
|
||||
this.iconUrl = iconUrl;
|
||||
}
|
||||
|
||||
private String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
private String getIconUrl() {
|
||||
return iconUrl;
|
||||
}
|
||||
}
|
||||
|
||||
private class Thumbnail {
|
||||
private String url;
|
||||
|
||||
private Thumbnail(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
private String getUrl() {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
private class Image {
|
||||
private String url;
|
||||
|
||||
private Image(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
private String getUrl() {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
private class Author {
|
||||
private String name;
|
||||
private String url;
|
||||
private String iconUrl;
|
||||
|
||||
private Author(String name, String url, String iconUrl) {
|
||||
this.name = name;
|
||||
this.url = url;
|
||||
this.iconUrl = iconUrl;
|
||||
}
|
||||
|
||||
private String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
private String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
private String getIconUrl() {
|
||||
return iconUrl;
|
||||
}
|
||||
}
|
||||
|
||||
private class Field {
|
||||
private String name;
|
||||
private String value;
|
||||
private boolean inline;
|
||||
|
||||
private Field(String name, String value, boolean inline) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.inline = inline;
|
||||
}
|
||||
|
||||
private String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
private String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
private boolean isInline() {
|
||||
return inline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class JSONObject {
|
||||
|
||||
private final HashMap<String, Object> map = new HashMap<>();
|
||||
|
||||
void put(String key, Object value) {
|
||||
if (value != null) {
|
||||
map.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Set<Map.Entry<String, Object>> entrySet = map.entrySet();
|
||||
builder.append("{");
|
||||
|
||||
int i = 0;
|
||||
for (Map.Entry<String, Object> entry : entrySet) {
|
||||
Object val = entry.getValue();
|
||||
builder.append(quote(entry.getKey())).append(":");
|
||||
|
||||
if (val instanceof String) {
|
||||
builder.append(quote(String.valueOf(val)));
|
||||
} else if (val instanceof Integer) {
|
||||
builder.append(Integer.valueOf(String.valueOf(val)));
|
||||
} else if (val instanceof Boolean) {
|
||||
builder.append(val);
|
||||
} else if (val instanceof JSONObject) {
|
||||
builder.append(val.toString());
|
||||
} else if (val.getClass().isArray()) {
|
||||
builder.append("[");
|
||||
int len = Array.getLength(val);
|
||||
for (int j = 0; j < len; j++) {
|
||||
builder.append(Array.get(val, j).toString()).append(j != len - 1 ? "," : "");
|
||||
}
|
||||
builder.append("]");
|
||||
}
|
||||
|
||||
builder.append(++i == entrySet.size() ? "}" : ",");
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private String quote(String string) {
|
||||
return "\"" + string + "\"";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
"ClientPlayerEntityMixin",
|
||||
"ClientPlayNetworkHandlerAccessor",
|
||||
"ClientPlayNetworkHandlerMixin",
|
||||
"ClientPlayNetworkHandlerInvoker",
|
||||
"DecoderHandlerMixin",
|
||||
"ElderGuardianAppearanceParticleMixin",
|
||||
"KeyboardInputMixin",
|
||||
|
@ -21,7 +22,12 @@
|
|||
"NbtIoMixin",
|
||||
"SessionMixin",
|
||||
"StringHelperMixin",
|
||||
"TitleScreenMixin"
|
||||
"TitleScreenMixin",
|
||||
"IdentifierMixin",
|
||||
"DecoratedPotBlockEntitySherdsMixin",
|
||||
"TextMixin",
|
||||
"ClientConnectionInvoker",
|
||||
"ClientConnectionAccessor"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
|
|
@ -15,7 +15,8 @@
|
|||
"sbot": { "prefix": ":", "key": null },
|
||||
"chipmunk": { "prefix": "'", "key": null },
|
||||
"chomens": { "prefix": "*", "key": null },
|
||||
"kittycorp": { "prefix": "^", "key": null }
|
||||
"kittycorp": { "prefix": "^", "key": null },
|
||||
"testbot": { "prefix": "-", "webhookUrl": null }
|
||||
},
|
||||
|
||||
"customChat": {
|
Loading…
Reference in a new issue