mirror of
https://code.chipmunk.land/ChomeNS/chipmunkmod.git
synced 2025-11-13 18:46:15 +00:00
refactor: use LF line endings and use 4 spaces on all classes
This commit is contained in:
parent
43527d9e6e
commit
50db974497
25 changed files with 2298 additions and 2255 deletions
|
|
@ -1,80 +1,80 @@
|
||||||
package land.chipmunk.chipmunkmod;
|
package land.chipmunk.chipmunkmod;
|
||||||
|
|
||||||
import land.chipmunk.chipmunkmod.config.ChipmunkModMigrations;
|
import land.chipmunk.chipmunkmod.config.ChipmunkModMigrations;
|
||||||
import land.chipmunk.chipmunkmod.config.Configuration;
|
import land.chipmunk.chipmunkmod.config.Configuration;
|
||||||
import land.chipmunk.chipmunkmod.modules.SelfCare;
|
import land.chipmunk.chipmunkmod.modules.SelfCare;
|
||||||
import land.chipmunk.chipmunkmod.util.configurate.ConfigurateUtilities;
|
import land.chipmunk.chipmunkmod.util.configurate.ConfigurateUtilities;
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.spongepowered.configurate.BasicConfigurationNode;
|
import org.spongepowered.configurate.BasicConfigurationNode;
|
||||||
import org.spongepowered.configurate.gson.GsonConfigurationLoader;
|
import org.spongepowered.configurate.gson.GsonConfigurationLoader;
|
||||||
import org.spongepowered.configurate.objectmapping.ObjectMapper;
|
import org.spongepowered.configurate.objectmapping.ObjectMapper;
|
||||||
import org.spongepowered.configurate.util.NamingSchemes;
|
import org.spongepowered.configurate.util.NamingSchemes;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
public class ChipmunkMod implements ModInitializer {
|
public class ChipmunkMod implements ModInitializer {
|
||||||
private static final Path CONFIG_PATH = FabricLoader.getInstance()
|
private static final Path CONFIG_PATH = FabricLoader.getInstance()
|
||||||
.getConfigDir().resolve("chipmunkmod.json");
|
.getConfigDir().resolve("chipmunkmod.json");
|
||||||
|
|
||||||
public static final Logger LOGGER = LoggerFactory.getLogger("ChipmunkMod");
|
public static final Logger LOGGER = LoggerFactory.getLogger("ChipmunkMod");
|
||||||
public static Configuration CONFIG;
|
public static Configuration CONFIG;
|
||||||
|
|
||||||
public static ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
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.
|
||||||
// However, some things (like resources) may still be uninitialized.
|
// However, some things (like resources) may still be uninitialized.
|
||||||
// Proceed with mild caution.
|
// Proceed with mild caution.
|
||||||
|
|
||||||
try {
|
try {
|
||||||
CONFIG = loadConfig();
|
CONFIG = loadConfig();
|
||||||
} catch (IOException exception) {
|
} catch (IOException exception) {
|
||||||
throw new RuntimeException("Could not load the config", exception);
|
throw new RuntimeException("Could not load the config", exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
SelfCare.INSTANCE.init();
|
SelfCare.INSTANCE.init();
|
||||||
|
|
||||||
LOGGER.info("Loaded ChipmunkMod (chayapak's fork)");
|
LOGGER.info("Loaded ChipmunkMod (chayapak's fork)");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Configuration loadConfig() throws IOException {
|
public static Configuration loadConfig() throws IOException {
|
||||||
final ChipmunkModMigrations migrations = new ChipmunkModMigrations();
|
final ChipmunkModMigrations migrations = new ChipmunkModMigrations();
|
||||||
final ObjectMapper.Factory customFactory = ObjectMapper.factoryBuilder()
|
final ObjectMapper.Factory customFactory = ObjectMapper.factoryBuilder()
|
||||||
.defaultNamingScheme(NamingSchemes.CAMEL_CASE)
|
.defaultNamingScheme(NamingSchemes.CAMEL_CASE)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final GsonConfigurationLoader loader = GsonConfigurationLoader.builder()
|
final GsonConfigurationLoader loader = GsonConfigurationLoader.builder()
|
||||||
.defaultOptions(options -> options
|
.defaultOptions(options -> options
|
||||||
.serializers(build -> build
|
.serializers(build -> build
|
||||||
.registerAnnotatedObjects(customFactory)
|
.registerAnnotatedObjects(customFactory)
|
||||||
.registerAll(ConfigurateUtilities.customSerializers()))
|
.registerAll(ConfigurateUtilities.customSerializers()))
|
||||||
.shouldCopyDefaults(true))
|
.shouldCopyDefaults(true))
|
||||||
.indent(4)
|
.indent(4)
|
||||||
.path(CONFIG_PATH)
|
.path(CONFIG_PATH)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
// Configurate will create parent directories for us, so we don't need to do it
|
// Configurate will create parent directories for us, so we don't need to do it
|
||||||
final BasicConfigurationNode node = loader.load();
|
final BasicConfigurationNode node = loader.load();
|
||||||
if (node.empty()) { // Config empty, fill it with defaults
|
if (node.empty()) { // Config empty, fill it with defaults
|
||||||
final Configuration defaults = new Configuration();
|
final Configuration defaults = new Configuration();
|
||||||
node.set(Configuration.class, defaults);
|
node.set(Configuration.class, defaults);
|
||||||
migrations.setLatest(node);
|
migrations.setLatest(node);
|
||||||
loader.save(node);
|
loader.save(node);
|
||||||
|
|
||||||
return defaults;
|
return defaults;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (migrations.migrate(node)) { // Migrated, write new config
|
if (migrations.migrate(node)) { // Migrated, write new config
|
||||||
loader.save(node);
|
loader.save(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
return node.get(Configuration.class);
|
return node.get(Configuration.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,86 +1,91 @@
|
||||||
package land.chipmunk.chipmunkmod.command;
|
package land.chipmunk.chipmunkmod.command;
|
||||||
|
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.mojang.brigadier.arguments.ArgumentType;
|
import com.mojang.brigadier.arguments.ArgumentType;
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import net.minecraft.text.ClickEvent;
|
import net.minecraft.text.ClickEvent;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.text.Texts;
|
import net.minecraft.text.Texts;
|
||||||
import net.minecraft.text.MutableText;
|
import net.minecraft.text.MutableText;
|
||||||
import net.minecraft.util.Formatting;
|
import net.minecraft.util.Formatting;
|
||||||
import net.minecraft.command.CommandRegistryAccess;
|
import net.minecraft.command.CommandRegistryAccess;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
||||||
import land.chipmunk.chipmunkmod.commands.*;
|
import land.chipmunk.chipmunkmod.commands.*;
|
||||||
|
|
||||||
public class CommandManager {
|
public class CommandManager {
|
||||||
public CommandDispatcher<FabricClientCommandSource> dispatcher = new CommandDispatcher<>();
|
public CommandDispatcher<FabricClientCommandSource> dispatcher = new CommandDispatcher<>();
|
||||||
public String prefix;
|
public String prefix;
|
||||||
|
|
||||||
public static CommandManager INSTANCE;
|
public static CommandManager INSTANCE;
|
||||||
|
|
||||||
public CommandManager (String prefix, CommandRegistryAccess commandRegistryAccess) {
|
public CommandManager(String prefix, CommandRegistryAccess commandRegistryAccess) {
|
||||||
this.prefix = prefix;
|
this.prefix = prefix;
|
||||||
|
|
||||||
TestCommand.register(this.dispatcher);
|
TestCommand.register(this.dispatcher);
|
||||||
CoreCommand.register(this.dispatcher);
|
CoreCommand.register(this.dispatcher);
|
||||||
UsernameCommand.register(this.dispatcher);
|
UsernameCommand.register(this.dispatcher);
|
||||||
CloopCommand.register(this.dispatcher);
|
CloopCommand.register(this.dispatcher);
|
||||||
ValidateCommand.register(this.dispatcher);
|
ValidateCommand.register(this.dispatcher);
|
||||||
ItemCommand.register(this.dispatcher, commandRegistryAccess);
|
ItemCommand.register(this.dispatcher, commandRegistryAccess);
|
||||||
CustomChatCommand.register(this.dispatcher);
|
CustomChatCommand.register(this.dispatcher);
|
||||||
EvalCommand.register(this.dispatcher);
|
EvalCommand.register(this.dispatcher);
|
||||||
MusicCommand.register(this.dispatcher);
|
MusicCommand.register(this.dispatcher);
|
||||||
RainbowNameCommand.register(this.dispatcher);
|
RainbowNameCommand.register(this.dispatcher);
|
||||||
SayCommand.register(this.dispatcher);
|
SayCommand.register(this.dispatcher);
|
||||||
AutoSkinCommand.register(this.dispatcher);
|
AutoSkinCommand.register(this.dispatcher);
|
||||||
ReloadConfigCommand.register(this.dispatcher);
|
ReloadConfigCommand.register(this.dispatcher);
|
||||||
SelfCareCommand.register(this.dispatcher);
|
SelfCareCommand.register(this.dispatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void executeCommand (String command) {
|
public void executeCommand(String command) {
|
||||||
final MinecraftClient client = MinecraftClient.getInstance();
|
final MinecraftClient client = MinecraftClient.getInstance();
|
||||||
|
|
||||||
final FabricClientCommandSource commandSource = (FabricClientCommandSource) client.getNetworkHandler().getCommandSource();
|
final FabricClientCommandSource commandSource = (FabricClientCommandSource) client.getNetworkHandler().getCommandSource();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
dispatcher.execute(command, commandSource);
|
dispatcher.execute(command, commandSource);
|
||||||
} catch (CommandSyntaxException e) {
|
} catch (CommandSyntaxException e) {
|
||||||
commandSource.sendError(Texts.toText(e.getRawMessage()));
|
commandSource.sendError(Texts.toText(e.getRawMessage()));
|
||||||
final Text context = getContext(e);
|
final Text context = getContext(e);
|
||||||
if (context != null) commandSource.sendError(context);
|
if (context != null) commandSource.sendError(context);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
commandSource.sendError(Text.of(e.getMessage()));
|
commandSource.sendError(Text.of(e.getMessage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Text getContext (CommandSyntaxException exception) {
|
public Text getContext(CommandSyntaxException exception) {
|
||||||
final int _cursor = exception.getCursor();
|
final int _cursor = exception.getCursor();
|
||||||
final String input = exception.getInput();
|
final String input = exception.getInput();
|
||||||
|
|
||||||
if (input == null || _cursor < 0) {
|
if (input == null || _cursor < 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final MutableText text = Text.literal("")
|
final MutableText text = Text.literal("")
|
||||||
.formatted(Formatting.GRAY);
|
.formatted(Formatting.GRAY);
|
||||||
text.setStyle(text.getStyle().withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, prefix + input)));
|
text.setStyle(text.getStyle().withClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, prefix + input)));
|
||||||
|
|
||||||
final int cursor = Math.min(input.length(), _cursor);
|
final int cursor = Math.min(input.length(), _cursor);
|
||||||
|
|
||||||
if (cursor > CommandSyntaxException.CONTEXT_AMOUNT) {
|
if (cursor > CommandSyntaxException.CONTEXT_AMOUNT) {
|
||||||
text.append(Text.literal("..."));
|
text.append(Text.literal("..."));
|
||||||
}
|
}
|
||||||
|
|
||||||
text
|
text
|
||||||
.append(Text.literal(input.substring(Math.max(0, cursor - CommandSyntaxException.CONTEXT_AMOUNT), cursor)))
|
.append(Text.literal(input.substring(Math.max(0, cursor - CommandSyntaxException.CONTEXT_AMOUNT), cursor)))
|
||||||
.append(Text.literal(input.substring(cursor)).formatted(Formatting.RED, Formatting.UNDERLINE))
|
.append(Text.literal(input.substring(cursor)).formatted(Formatting.RED, Formatting.UNDERLINE))
|
||||||
.append(Text.translatable("command.context.here").formatted(Formatting.RED, Formatting.ITALIC));
|
.append(Text.translatable("command.context.here").formatted(Formatting.RED, Formatting.ITALIC));
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LiteralArgumentBuilder<FabricClientCommandSource> literal (String name) { return LiteralArgumentBuilder.literal(name); }
|
public static LiteralArgumentBuilder<FabricClientCommandSource> literal(String name) {
|
||||||
public static <T> RequiredArgumentBuilder<FabricClientCommandSource, T> argument (String name, ArgumentType<T> type) { return RequiredArgumentBuilder.argument(name, type); }
|
return LiteralArgumentBuilder.literal(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> RequiredArgumentBuilder<FabricClientCommandSource, T> argument(String name, ArgumentType<T> type) {
|
||||||
|
return RequiredArgumentBuilder.argument(name, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,106 +1,108 @@
|
||||||
package land.chipmunk.chipmunkmod.commands;
|
package land.chipmunk.chipmunkmod.commands;
|
||||||
|
|
||||||
import com.google.common.base.Suppliers;
|
import com.google.common.base.Suppliers;
|
||||||
import com.mojang.brigadier.Command;
|
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 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 land.chipmunk.chipmunkmod.command.CommandManager.literal;
|
import static land.chipmunk.chipmunkmod.command.CommandManager.literal;
|
||||||
import static land.chipmunk.chipmunkmod.command.CommandManager.argument;
|
import static land.chipmunk.chipmunkmod.command.CommandManager.argument;
|
||||||
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
|
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
|
||||||
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
|
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
|
||||||
|
|
||||||
import land.chipmunk.chipmunkmod.util.TextUtilities;
|
import land.chipmunk.chipmunkmod.util.TextUtilities;
|
||||||
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;
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import land.chipmunk.chipmunkmod.modules.CommandCore;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class CoreCommand {
|
import land.chipmunk.chipmunkmod.modules.CommandCore;
|
||||||
public static void register (CommandDispatcher<FabricClientCommandSource> dispatcher) {
|
|
||||||
dispatcher.register(
|
public class CoreCommand {
|
||||||
literal("core")
|
public static void register(CommandDispatcher<FabricClientCommandSource> dispatcher) {
|
||||||
.then(
|
dispatcher.register(
|
||||||
literal("run")
|
literal("core")
|
||||||
.then(
|
.then(
|
||||||
argument("command", greedyString())
|
literal("run")
|
||||||
.executes(c -> run(c))
|
.then(
|
||||||
)
|
argument("command", greedyString())
|
||||||
)
|
.executes(c -> run(c))
|
||||||
|
)
|
||||||
.then(
|
)
|
||||||
literal("runTracked")
|
|
||||||
.then(
|
.then(
|
||||||
argument("command", greedyString())
|
literal("runTracked")
|
||||||
.executes(c -> runTracked(c))
|
.then(
|
||||||
)
|
argument("command", greedyString())
|
||||||
)
|
.executes(c -> runTracked(c))
|
||||||
|
)
|
||||||
.then(literal("refill").executes(c -> refill(c)))
|
)
|
||||||
.then(literal("move").executes(c -> move(c)))
|
|
||||||
|
.then(literal("refill").executes(c -> refill(c)))
|
||||||
.then(
|
.then(literal("move").executes(c -> move(c)))
|
||||||
literal("runFillCommand")
|
|
||||||
.then(
|
.then(
|
||||||
argument("enabled", bool())
|
literal("runFillCommand")
|
||||||
.executes(c -> runFillCommand(c))
|
.then(
|
||||||
)
|
argument("enabled", bool())
|
||||||
)
|
.executes(c -> runFillCommand(c))
|
||||||
);
|
)
|
||||||
}
|
)
|
||||||
|
);
|
||||||
public static int run (CommandContext<FabricClientCommandSource> context) {
|
}
|
||||||
CommandCore.INSTANCE.run(getString(context, "command"));
|
|
||||||
|
public static int run(CommandContext<FabricClientCommandSource> context) {
|
||||||
return Command.SINGLE_SUCCESS;
|
CommandCore.INSTANCE.run(getString(context, "command"));
|
||||||
}
|
|
||||||
|
return Command.SINGLE_SUCCESS;
|
||||||
public static int runTracked (CommandContext<FabricClientCommandSource> context) {
|
}
|
||||||
final FabricClientCommandSource source = context.getSource();
|
|
||||||
|
public static int runTracked(CommandContext<FabricClientCommandSource> context) {
|
||||||
final String command = getString(context, "command");
|
final FabricClientCommandSource source = context.getSource();
|
||||||
|
|
||||||
final CompletableFuture<NbtCompound> future = CommandCore.INSTANCE.runTracked(command);
|
final String command = getString(context, "command");
|
||||||
future.thenApply(tag -> {
|
|
||||||
try {
|
final CompletableFuture<NbtCompound> future = CommandCore.INSTANCE.runTracked(command);
|
||||||
final String output = tag.getString("LastOutput");
|
future.thenApply(tag -> {
|
||||||
if (output != null) source.sendFeedback(TextUtilities.fromJson(output));
|
try {
|
||||||
} catch (Exception e) {
|
final String output = tag.getString("LastOutput");
|
||||||
e.printStackTrace();
|
if (output != null) source.sendFeedback(TextUtilities.fromJson(output));
|
||||||
}
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
return tag;
|
}
|
||||||
});
|
|
||||||
|
return tag;
|
||||||
return Command.SINGLE_SUCCESS;
|
});
|
||||||
}
|
|
||||||
|
return Command.SINGLE_SUCCESS;
|
||||||
public static int refill (CommandContext<FabricClientCommandSource> context) {
|
}
|
||||||
CommandCore.INSTANCE.refill();
|
|
||||||
|
public static int refill(CommandContext<FabricClientCommandSource> context) {
|
||||||
return Command.SINGLE_SUCCESS;
|
CommandCore.INSTANCE.refill();
|
||||||
}
|
|
||||||
|
return Command.SINGLE_SUCCESS;
|
||||||
public static int move (CommandContext<FabricClientCommandSource> context) {
|
}
|
||||||
final FabricClientCommandSource source = context.getSource();
|
|
||||||
|
public static int move(CommandContext<FabricClientCommandSource> context) {
|
||||||
CommandCore.INSTANCE.move(source.getClient().player.getPos());
|
final FabricClientCommandSource source = context.getSource();
|
||||||
|
|
||||||
return Command.SINGLE_SUCCESS;
|
CommandCore.INSTANCE.move(source.getClient().player.getPos());
|
||||||
}
|
|
||||||
|
return Command.SINGLE_SUCCESS;
|
||||||
public static int runFillCommand(CommandContext<FabricClientCommandSource> context) {
|
}
|
||||||
final FabricClientCommandSource source = context.getSource();
|
|
||||||
|
public static int runFillCommand(CommandContext<FabricClientCommandSource> context) {
|
||||||
final boolean bool = getBool(context, "enabled");
|
final FabricClientCommandSource source = context.getSource();
|
||||||
|
|
||||||
CommandCore.INSTANCE.runFillCommand = bool;
|
final boolean bool = getBool(context, "enabled");
|
||||||
|
|
||||||
source.sendFeedback(Text.literal("Running fill commands are now " + (bool ? "enabled" : "disabled")));
|
CommandCore.INSTANCE.runFillCommand = bool;
|
||||||
|
|
||||||
return Command.SINGLE_SUCCESS;
|
source.sendFeedback(Text.literal("Running fill commands is now " + (bool ? "enabled" : "disabled")));
|
||||||
}
|
|
||||||
}
|
return Command.SINGLE_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,14 @@ 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 com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
|
|
||||||
import static land.chipmunk.chipmunkmod.command.CommandManager.literal;
|
import static land.chipmunk.chipmunkmod.command.CommandManager.literal;
|
||||||
import static land.chipmunk.chipmunkmod.command.CommandManager.argument;
|
import static land.chipmunk.chipmunkmod.command.CommandManager.argument;
|
||||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
||||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
|
import static com.mojang.brigadier.arguments.IntegerArgumentType.getInteger;
|
||||||
import static net.minecraft.command.argument.ItemStackArgumentType.itemStack;
|
import static net.minecraft.command.argument.ItemStackArgumentType.itemStack;
|
||||||
import static net.minecraft.command.argument.ItemStackArgumentType.getItemStackArgument;
|
import static net.minecraft.command.argument.ItemStackArgumentType.getItemStackArgument;
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
||||||
import net.minecraft.command.CommandRegistryAccess;
|
import net.minecraft.command.CommandRegistryAccess;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
|
@ -18,7 +20,7 @@ import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
public class ItemCommand {
|
public class ItemCommand {
|
||||||
public static void register (CommandDispatcher<FabricClientCommandSource> dispatcher, CommandRegistryAccess commandRegistryAccess) {
|
public static void register(CommandDispatcher<FabricClientCommandSource> dispatcher, CommandRegistryAccess commandRegistryAccess) {
|
||||||
dispatcher.register(
|
dispatcher.register(
|
||||||
literal("item")
|
literal("item")
|
||||||
.then(
|
.then(
|
||||||
|
|
@ -32,11 +34,11 @@ public class ItemCommand {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int setItem (CommandContext<FabricClientCommandSource> context) throws CommandSyntaxException {
|
public static int setItem(CommandContext<FabricClientCommandSource> context) throws CommandSyntaxException {
|
||||||
return setItem(context, getInteger(context, "count"));
|
return setItem(context, getInteger(context, "count"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int setItem (CommandContext<FabricClientCommandSource> context, int count) throws CommandSyntaxException {
|
public static int setItem(CommandContext<FabricClientCommandSource> context, int count) throws CommandSyntaxException {
|
||||||
final FabricClientCommandSource source = context.getSource();
|
final FabricClientCommandSource source = context.getSource();
|
||||||
final MinecraftClient client = source.getClient();
|
final MinecraftClient client = source.getClient();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,26 @@
|
||||||
package land.chipmunk.chipmunkmod.commands;
|
package land.chipmunk.chipmunkmod.commands;
|
||||||
|
|
||||||
import com.mojang.brigadier.Command;
|
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 static land.chipmunk.chipmunkmod.command.CommandManager.literal;
|
|
||||||
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
import static land.chipmunk.chipmunkmod.command.CommandManager.literal;
|
||||||
import net.minecraft.text.Text;
|
|
||||||
|
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
||||||
public class TestCommand {
|
import net.minecraft.text.Text;
|
||||||
public static void register (CommandDispatcher<FabricClientCommandSource> dispatcher) {
|
|
||||||
dispatcher.register(
|
public class TestCommand {
|
||||||
literal("test")
|
public static void register(CommandDispatcher<FabricClientCommandSource> dispatcher) {
|
||||||
.executes(c -> helloWorld(c))
|
dispatcher.register(
|
||||||
);
|
literal("test")
|
||||||
}
|
.executes(c -> helloWorld(c))
|
||||||
|
);
|
||||||
public static int helloWorld (CommandContext<FabricClientCommandSource> context) {
|
}
|
||||||
final FabricClientCommandSource source = context.getSource();
|
|
||||||
source.sendFeedback(Text.literal("Hello, world!"));
|
public static int helloWorld(CommandContext<FabricClientCommandSource> context) {
|
||||||
|
final FabricClientCommandSource source = context.getSource();
|
||||||
return Command.SINGLE_SUCCESS;
|
source.sendFeedback(Text.literal("Hello, world!"));
|
||||||
}
|
|
||||||
}
|
return Command.SINGLE_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,68 +1,71 @@
|
||||||
package land.chipmunk.chipmunkmod.commands;
|
package land.chipmunk.chipmunkmod.commands;
|
||||||
|
|
||||||
import com.mojang.brigadier.Command;
|
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 static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
|
|
||||||
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
|
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
|
||||||
import static land.chipmunk.chipmunkmod.command.CommandManager.literal;
|
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
|
||||||
import static land.chipmunk.chipmunkmod.command.CommandManager.argument;
|
import static land.chipmunk.chipmunkmod.command.CommandManager.literal;
|
||||||
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
import static land.chipmunk.chipmunkmod.command.CommandManager.argument;
|
||||||
import net.minecraft.client.MinecraftClient;
|
|
||||||
import net.minecraft.client.gui.screen.TitleScreen;
|
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
||||||
import net.minecraft.client.gui.screen.multiplayer.ConnectScreen;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.network.ServerInfo;
|
import net.minecraft.client.gui.screen.TitleScreen;
|
||||||
import net.minecraft.client.network.ServerAddress;
|
import net.minecraft.client.gui.screen.multiplayer.ConnectScreen;
|
||||||
import net.minecraft.client.session.Session;
|
import net.minecraft.client.network.ServerInfo;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.client.network.ServerAddress;
|
||||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
import net.minecraft.client.session.Session;
|
||||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
import net.minecraft.text.Text;
|
||||||
import java.util.Optional;
|
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||||
import java.util.UUID;
|
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||||
|
|
||||||
import land.chipmunk.chipmunkmod.mixin.MinecraftClientAccessor;
|
import java.util.Optional;
|
||||||
|
import java.util.UUID;
|
||||||
public class UsernameCommand {
|
|
||||||
private static final Session ORIGINAL_SESSION = MinecraftClient.getInstance().getSession();
|
import land.chipmunk.chipmunkmod.mixin.MinecraftClientAccessor;
|
||||||
private static final SimpleCommandExceptionType USERNAME_TOO_LONG = new SimpleCommandExceptionType(Text.translatable("The specified username is longer than 16 characters"));
|
|
||||||
|
public class UsernameCommand {
|
||||||
public static void register (CommandDispatcher<FabricClientCommandSource> dispatcher) {
|
private static final Session ORIGINAL_SESSION = MinecraftClient.getInstance().getSession();
|
||||||
dispatcher.register(
|
private static final SimpleCommandExceptionType USERNAME_TOO_LONG = new SimpleCommandExceptionType(Text.translatable("The specified username is longer than 16 characters"));
|
||||||
literal("username")
|
|
||||||
.then(
|
public static void register(CommandDispatcher<FabricClientCommandSource> dispatcher) {
|
||||||
literal("set")
|
dispatcher.register(
|
||||||
.then(
|
literal("username")
|
||||||
argument("username", greedyString())
|
.then(
|
||||||
.executes(c -> updateUsername(c))
|
literal("set")
|
||||||
)
|
.then(
|
||||||
)
|
argument("username", greedyString())
|
||||||
.then(
|
.executes(c -> updateUsername(c))
|
||||||
literal("revert")
|
)
|
||||||
.executes(c -> updateSession(c, ORIGINAL_SESSION))
|
)
|
||||||
)
|
.then(
|
||||||
);
|
literal("revert")
|
||||||
}
|
.executes(c -> updateSession(c, ORIGINAL_SESSION))
|
||||||
|
)
|
||||||
public static int updateUsername (CommandContext<FabricClientCommandSource> context) throws CommandSyntaxException {
|
);
|
||||||
final String username = getString(context, "username");
|
}
|
||||||
if (username.length() > 16) throw USERNAME_TOO_LONG.create();
|
|
||||||
final Session session = new Session(username, new UUID(0L, 0L), "", Optional.empty(), Optional.empty(), Session.AccountType.MOJANG);
|
public static int updateUsername(CommandContext<FabricClientCommandSource> context) throws CommandSyntaxException {
|
||||||
return updateSession(context, session);
|
final String username = getString(context, "username");
|
||||||
}
|
if (username.length() > 16) throw USERNAME_TOO_LONG.create();
|
||||||
|
final Session session = new Session(username, new UUID(0L, 0L), "", Optional.empty(), Optional.empty(), Session.AccountType.MOJANG);
|
||||||
public static int updateSession (CommandContext<FabricClientCommandSource> context, Session session) throws CommandSyntaxException {
|
return updateSession(context, session);
|
||||||
final FabricClientCommandSource source = context.getSource();
|
}
|
||||||
|
|
||||||
final MinecraftClient client = source.getClient();
|
public static int updateSession(CommandContext<FabricClientCommandSource> context, Session session) throws CommandSyntaxException {
|
||||||
|
final FabricClientCommandSource source = context.getSource();
|
||||||
((MinecraftClientAccessor) client).session(session);
|
|
||||||
|
final MinecraftClient client = source.getClient();
|
||||||
// TODO: Put this in a separate class
|
|
||||||
final ServerInfo info = client.getCurrentServerEntry();
|
((MinecraftClientAccessor) client).session(session);
|
||||||
client.world.disconnect();
|
|
||||||
client.disconnect();
|
// TODO: Put this in a separate class
|
||||||
ConnectScreen.connect(new TitleScreen(), client, ServerAddress.parse(info.address), info, false, null);
|
final ServerInfo info = client.getCurrentServerEntry();
|
||||||
|
client.world.disconnect();
|
||||||
return Command.SINGLE_SUCCESS;
|
client.disconnect();
|
||||||
}
|
ConnectScreen.connect(new TitleScreen(), client, ServerAddress.parse(info.address), info, false, null);
|
||||||
}
|
|
||||||
|
return Command.SINGLE_SUCCESS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,30 @@
|
||||||
package land.chipmunk.chipmunkmod.commands;
|
package land.chipmunk.chipmunkmod.commands;
|
||||||
|
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
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;
|
||||||
|
|
||||||
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
|
import static com.mojang.brigadier.arguments.StringArgumentType.getString;
|
||||||
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
|
import static com.mojang.brigadier.arguments.StringArgumentType.greedyString;
|
||||||
import static land.chipmunk.chipmunkmod.command.CommandManager.argument;
|
import static land.chipmunk.chipmunkmod.command.CommandManager.argument;
|
||||||
import static land.chipmunk.chipmunkmod.command.CommandManager.literal;
|
import static land.chipmunk.chipmunkmod.command.CommandManager.literal;
|
||||||
import static land.chipmunk.chipmunkmod.util.BotValidationUtilities.*;
|
import static land.chipmunk.chipmunkmod.util.BotValidationUtilities.*;
|
||||||
|
|
||||||
public class ValidateCommand {
|
public class ValidateCommand {
|
||||||
public static void register (CommandDispatcher<FabricClientCommandSource> dispatcher) {
|
public static void register(CommandDispatcher<FabricClientCommandSource> dispatcher) {
|
||||||
dispatcher.register(
|
dispatcher.register(
|
||||||
literal("validate")
|
literal("validate")
|
||||||
.then(literal("hbot").then(argument("command", greedyString()).executes(c -> hbot(getString(c, "command")))))
|
.then(literal("hbot").then(argument("command", greedyString()).executes(c -> hbot(getString(c, "command")))))
|
||||||
.then(literal("sbot").then(argument("command", greedyString()).executes(c -> sbot(getString(c, "command")))))
|
.then(literal("sbot").then(argument("command", greedyString()).executes(c -> sbot(getString(c, "command")))))
|
||||||
// .then(literal("chipmunk").then(argument("command", greedyString()).executes(c -> chipmunk(getString(c, "command")))))
|
// .then(literal("chipmunk").then(argument("command", greedyString()).executes(c -> chipmunk(getString(c, "command")))))
|
||||||
.then(literal("chomens").then(argument("command", greedyString()).executes(c -> {
|
.then(literal("chomens").then(argument("command", greedyString()).executes(c -> {
|
||||||
c.getSource().sendFeedback(Text.literal("Warning: Manual ChomeNS Bot validation is deprecated. Please use the completions from typing the bot's prefix."));
|
c.getSource().sendFeedback(Text.literal("Warning: Manual ChomeNS Bot validation is deprecated. Please use the completions from typing the bot's prefix."));
|
||||||
|
|
||||||
return chomens(getString(c, "command"));
|
return chomens(getString(c, "command"));
|
||||||
})))
|
})))
|
||||||
.then(literal("fnfboyfriend").then(argument("command", greedyString()).executes(c -> fnfboyfriend(getString(c, "command")))))
|
.then(literal("fnfboyfriend").then(argument("command", greedyString()).executes(c -> fnfboyfriend(getString(c, "command")))))
|
||||||
.then(literal("nbot").then(argument("command", greedyString()).executes(c -> nbot(getString(c, "command")))))
|
.then(literal("nbot").then(argument("command", greedyString()).executes(c -> nbot(getString(c, "command")))))
|
||||||
.then(literal("kittycorp").then(argument("command", greedyString()).executes(c -> kittycorp(getString(c, "command")))))
|
.then(literal("kittycorp").then(argument("command", greedyString()).executes(c -> kittycorp(getString(c, "command")))))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,80 +9,86 @@ import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
||||||
|
|
||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
public class Configuration {
|
public class Configuration {
|
||||||
public CommandManager commands = new CommandManager();
|
public CommandManager commands = new CommandManager();
|
||||||
public CommandCore core = new CommandCore();
|
public CommandCore core = new CommandCore();
|
||||||
public Bots bots = new Bots();
|
public Bots bots = new Bots();
|
||||||
public CustomChat customChat = new CustomChat();
|
public CustomChat customChat = new CustomChat();
|
||||||
public String autoSkinUsername = "off";
|
public String autoSkinUsername = "off";
|
||||||
|
|
||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
public static class CommandManager {
|
public static class CommandManager {
|
||||||
public String prefix = ".";
|
public String prefix = ".";
|
||||||
}
|
|
||||||
|
|
||||||
@ConfigSerializable
|
|
||||||
public static class CommandCore {
|
|
||||||
public BlockBox relativeArea = BlockBox.create(new BlockPos(0, 0, 0), new BlockPos(15, 0, 15));
|
|
||||||
}
|
|
||||||
|
|
||||||
@ConfigSerializable
|
|
||||||
public static class Bots {
|
|
||||||
public BotInfo hbot = new BotInfo("#", null);
|
|
||||||
public BotInfo sbot = new BotInfo(":", null);
|
|
||||||
public BotInfo chipmunk = new BotInfo("'", null);
|
|
||||||
public ChomeNSBotInfo chomens = new ChomeNSBotInfo("*", null, null, null);
|
|
||||||
public BotInfo fnfboyfriend = new BotInfo("~", null);
|
|
||||||
public BotInfo nbot = new BotInfo("?", null);
|
|
||||||
public BotInfo kittycorp = new BotInfo("^", null);
|
|
||||||
public TestBotInfo testbot = new TestBotInfo("-", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@ConfigSerializable
|
|
||||||
public static class ChomeNSBotInfo {
|
|
||||||
public String prefix;
|
|
||||||
public @Nullable String key;
|
|
||||||
public @Nullable String authKey;
|
|
||||||
public @Nullable String formatKey;
|
|
||||||
|
|
||||||
public ChomeNSBotInfo() {}
|
|
||||||
public ChomeNSBotInfo (String prefix, @Nullable String key, @Nullable String authKey, @Nullable String formatKey) {
|
|
||||||
this.prefix = prefix;
|
|
||||||
this.key = key;
|
|
||||||
this.authKey = authKey;
|
|
||||||
this.formatKey = formatKey;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
public static class TestBotInfo {
|
public static class CommandCore {
|
||||||
public String prefix;
|
public BlockBox relativeArea = BlockBox.create(new BlockPos(0, 0, 0), new BlockPos(15, 0, 15));
|
||||||
public @Nullable String webhookUrl;
|
|
||||||
|
|
||||||
public TestBotInfo() {}
|
|
||||||
public TestBotInfo (String prefix, @Nullable String webhookUrl) {
|
|
||||||
this.prefix = prefix;
|
|
||||||
this.webhookUrl = webhookUrl;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
public static class BotInfo {
|
public static class Bots {
|
||||||
public String prefix;
|
public BotInfo hbot = new BotInfo("#", null);
|
||||||
public @Nullable String key;
|
public BotInfo sbot = new BotInfo(":", null);
|
||||||
|
public BotInfo chipmunk = new BotInfo("'", null);
|
||||||
public BotInfo() {}
|
public ChomeNSBotInfo chomens = new ChomeNSBotInfo("*", null, null, null);
|
||||||
public BotInfo (String prefix, @Nullable String key) {
|
public BotInfo fnfboyfriend = new BotInfo("~", null);
|
||||||
this.prefix = prefix;
|
public BotInfo nbot = new BotInfo("?", null);
|
||||||
this.key = key;
|
public BotInfo kittycorp = new BotInfo("^", null);
|
||||||
|
public TestBotInfo testbot = new TestBotInfo("-", null);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@ConfigSerializable
|
@ConfigSerializable
|
||||||
public static class CustomChat {
|
public static class ChomeNSBotInfo {
|
||||||
public @NotNull Component format =
|
public String prefix;
|
||||||
Component.translatable("chat.type.text",
|
public @Nullable String key;
|
||||||
Component.selector("@s"),
|
public @Nullable String authKey;
|
||||||
Component.text("MESSAGE")
|
public @Nullable String formatKey;
|
||||||
);
|
|
||||||
}
|
public ChomeNSBotInfo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChomeNSBotInfo(String prefix, @Nullable String key, @Nullable String authKey, @Nullable String formatKey) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.key = key;
|
||||||
|
this.authKey = authKey;
|
||||||
|
this.formatKey = formatKey;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigSerializable
|
||||||
|
public static class TestBotInfo {
|
||||||
|
public String prefix;
|
||||||
|
public @Nullable String webhookUrl;
|
||||||
|
|
||||||
|
public TestBotInfo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestBotInfo(String prefix, @Nullable String webhookUrl) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.webhookUrl = webhookUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigSerializable
|
||||||
|
public static class BotInfo {
|
||||||
|
public String prefix;
|
||||||
|
public @Nullable String key;
|
||||||
|
|
||||||
|
public BotInfo() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public BotInfo(String prefix, @Nullable String key) {
|
||||||
|
this.prefix = prefix;
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ConfigSerializable
|
||||||
|
public static class CustomChat {
|
||||||
|
public @NotNull Component format =
|
||||||
|
Component.translatable("chat.type.text",
|
||||||
|
Component.selector("@s"),
|
||||||
|
Component.text("MESSAGE")
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,10 +27,10 @@ public record ChomeNSBotCommand(String name, TrustLevel trustLevel, List<String>
|
||||||
ChipmunkMod.CONFIG.bots.chomens.prefix + name, trustLevel, List.of());
|
ChipmunkMod.CONFIG.bots.chomens.prefix + name, trustLevel, List.of());
|
||||||
|
|
||||||
final List<String> aliases = children.stream()
|
final List<String> aliases = children.stream()
|
||||||
.skip(2)
|
.skip(2)
|
||||||
.map(TextUtilities::plainOrNull)
|
.map(TextUtilities::plainOrNull)
|
||||||
.filter(Objects::nonNull)
|
.filter(Objects::nonNull)
|
||||||
.toList();
|
.toList();
|
||||||
return new ChomeNSBotCommand(
|
return new ChomeNSBotCommand(
|
||||||
ChipmunkMod.CONFIG.bots.chomens.prefix + name, trustLevel, aliases);
|
ChipmunkMod.CONFIG.bots.chomens.prefix + name, trustLevel, aliases);
|
||||||
}
|
}
|
||||||
|
|
@ -47,7 +47,8 @@ public record ChomeNSBotCommand(String name, TrustLevel trustLevel, List<String>
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return TrustLevel.valueOf(trustLevelString);
|
return TrustLevel.valueOf(trustLevelString);
|
||||||
} catch (final IllegalArgumentException ignored) {}
|
} catch (final IllegalArgumentException ignored) {
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,99 +1,100 @@
|
||||||
package land.chipmunk.chipmunkmod.mixin;
|
package land.chipmunk.chipmunkmod.mixin;
|
||||||
|
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.mojang.brigadier.StringReader;
|
import com.mojang.brigadier.StringReader;
|
||||||
import com.mojang.brigadier.suggestion.Suggestions;
|
import com.mojang.brigadier.suggestion.Suggestions;
|
||||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||||
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
||||||
import land.chipmunk.chipmunkmod.command.CommandManager;
|
import land.chipmunk.chipmunkmod.command.CommandManager;
|
||||||
import land.chipmunk.chipmunkmod.data.ChomeNSBotCommand;
|
import land.chipmunk.chipmunkmod.data.ChomeNSBotCommand;
|
||||||
import land.chipmunk.chipmunkmod.modules.ChomeNSBotCommandSuggestions;
|
import land.chipmunk.chipmunkmod.modules.ChomeNSBotCommandSuggestions;
|
||||||
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||||
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.command.CommandSource;
|
import net.minecraft.command.CommandSource;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Mutable;
|
import org.spongepowered.asm.mixin.Mutable;
|
||||||
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 java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
@Mixin(net.minecraft.client.gui.screen.ChatInputSuggestor.class)
|
@Mixin(net.minecraft.client.gui.screen.ChatInputSuggestor.class)
|
||||||
public class ChatInputSuggestorMixin {
|
public class ChatInputSuggestorMixin {
|
||||||
@Shadow
|
@Shadow
|
||||||
private CompletableFuture<Suggestions> pendingSuggestions;
|
private CompletableFuture<Suggestions> pendingSuggestions;
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
public void show (boolean narrateFirstSuggestion) {}
|
public void show(boolean narrateFirstSuggestion) {
|
||||||
|
}
|
||||||
@Shadow
|
|
||||||
private static int getStartOfCurrentWord (String input) {
|
@Shadow
|
||||||
return 0;
|
private static int getStartOfCurrentWord(String input) {
|
||||||
}
|
return 0;
|
||||||
|
}
|
||||||
@Mutable
|
|
||||||
@Final
|
@Mutable
|
||||||
@Shadow
|
@Final
|
||||||
final TextFieldWidget textField;
|
@Shadow
|
||||||
|
final TextFieldWidget textField;
|
||||||
public ChatInputSuggestorMixin () {
|
|
||||||
textField = null;
|
public ChatInputSuggestorMixin() {
|
||||||
}
|
textField = null;
|
||||||
|
}
|
||||||
@Inject(at = @At("TAIL"), method = "refresh()V")
|
|
||||||
public void refresh (CallbackInfo ci) {
|
@Inject(at = @At("TAIL"), method = "refresh()V")
|
||||||
final CommandManager commandManager = CommandManager.INSTANCE;
|
public void refresh(CallbackInfo ci) {
|
||||||
|
final CommandManager commandManager = CommandManager.INSTANCE;
|
||||||
final String text = this.textField.getText();
|
|
||||||
final int cursor = this.textField.getCursor();
|
final String text = this.textField.getText();
|
||||||
|
final int cursor = this.textField.getCursor();
|
||||||
final ClientPlayerEntity player = MinecraftClient.getInstance().player;
|
|
||||||
|
final ClientPlayerEntity player = MinecraftClient.getInstance().player;
|
||||||
final String chomeNSPrefix = ChipmunkMod.CONFIG.bots.chomens.prefix;
|
|
||||||
|
final String chomeNSPrefix = ChipmunkMod.CONFIG.bots.chomens.prefix;
|
||||||
if (!text.contains(" ") && text.startsWith(chomeNSPrefix) && player != null) {
|
|
||||||
final String textUpToCursor = text.substring(0, cursor);
|
if (!text.contains(" ") && text.startsWith(chomeNSPrefix) && player != null) {
|
||||||
|
final String textUpToCursor = text.substring(0, cursor);
|
||||||
final List<String> commands = ChomeNSBotCommandSuggestions.INSTANCE.commands
|
|
||||||
.stream()
|
final List<String> commands = ChomeNSBotCommandSuggestions.INSTANCE.commands
|
||||||
.map(ChomeNSBotCommand::name)
|
.stream()
|
||||||
.toList();
|
.map(ChomeNSBotCommand::name)
|
||||||
|
.toList();
|
||||||
pendingSuggestions = CommandSource.suggestMatching(
|
|
||||||
commands,
|
pendingSuggestions = CommandSource.suggestMatching(
|
||||||
new SuggestionsBuilder(
|
commands,
|
||||||
textUpToCursor,
|
new SuggestionsBuilder(
|
||||||
getStartOfCurrentWord(textUpToCursor)
|
textUpToCursor,
|
||||||
)
|
getStartOfCurrentWord(textUpToCursor)
|
||||||
);
|
)
|
||||||
|
);
|
||||||
pendingSuggestions.thenRun(() -> {
|
|
||||||
if (!pendingSuggestions.isDone()) return;
|
pendingSuggestions.thenRun(() -> {
|
||||||
|
if (!pendingSuggestions.isDone()) return;
|
||||||
show(true);
|
|
||||||
});
|
show(true);
|
||||||
} else if (cursor >= commandManager.prefix.length() && text.startsWith(commandManager.prefix)) {
|
});
|
||||||
final StringReader reader = new StringReader(text);
|
} else if (cursor >= commandManager.prefix.length() && text.startsWith(commandManager.prefix)) {
|
||||||
reader.setCursor(commandManager.prefix.length()); // Skip the prefix
|
final StringReader reader = new StringReader(text);
|
||||||
|
reader.setCursor(commandManager.prefix.length()); // Skip the prefix
|
||||||
final MinecraftClient client = MinecraftClient.getInstance();
|
|
||||||
|
final MinecraftClient client = MinecraftClient.getInstance();
|
||||||
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
|
||||||
|
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
||||||
if (networkHandler == null) return;
|
|
||||||
|
if (networkHandler == null) return;
|
||||||
final CommandDispatcher<FabricClientCommandSource> dispatcher = commandManager.dispatcher;
|
|
||||||
final FabricClientCommandSource commandSource = (FabricClientCommandSource) networkHandler.getCommandSource();
|
final CommandDispatcher<FabricClientCommandSource> dispatcher = commandManager.dispatcher;
|
||||||
|
final FabricClientCommandSource commandSource = (FabricClientCommandSource) networkHandler.getCommandSource();
|
||||||
pendingSuggestions = dispatcher.getCompletionSuggestions(dispatcher.parse(reader, commandSource), cursor);
|
|
||||||
show(true);
|
pendingSuggestions = dispatcher.getCompletionSuggestions(dispatcher.parse(reader, commandSource), cursor);
|
||||||
}
|
show(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,147 +1,153 @@
|
||||||
package land.chipmunk.chipmunkmod.mixin;
|
package land.chipmunk.chipmunkmod.mixin;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
||||||
import land.chipmunk.chipmunkmod.data.ChomeNSBotCommand;
|
import land.chipmunk.chipmunkmod.data.ChomeNSBotCommand;
|
||||||
import land.chipmunk.chipmunkmod.modules.ChomeNSBotCommandSuggestions;
|
import land.chipmunk.chipmunkmod.modules.ChomeNSBotCommandSuggestions;
|
||||||
import land.chipmunk.chipmunkmod.util.BotValidationUtilities;
|
import land.chipmunk.chipmunkmod.util.BotValidationUtilities;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.gui.screen.ChatInputSuggestor;
|
import net.minecraft.client.gui.screen.ChatInputSuggestor;
|
||||||
import net.minecraft.client.gui.screen.Screen;
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
import net.minecraft.client.gui.widget.TextFieldWidget;
|
import net.minecraft.client.gui.widget.TextFieldWidget;
|
||||||
import net.minecraft.text.MutableText;
|
import net.minecraft.text.MutableText;
|
||||||
import net.minecraft.text.Text;
|
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.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Mixin(value = net.minecraft.client.gui.screen.ChatScreen.class)
|
@Mixin(value = net.minecraft.client.gui.screen.ChatScreen.class)
|
||||||
public abstract class ChatScreenMixin extends Screen {
|
public abstract class ChatScreenMixin extends Screen {
|
||||||
@Shadow private String originalChatText;
|
@Shadow
|
||||||
|
private String originalChatText;
|
||||||
@Shadow private int messageHistoryIndex;
|
|
||||||
|
@Shadow
|
||||||
@Shadow protected TextFieldWidget chatField;
|
private int messageHistoryIndex;
|
||||||
|
|
||||||
@Shadow ChatInputSuggestor chatInputSuggestor;
|
@Shadow
|
||||||
|
protected TextFieldWidget chatField;
|
||||||
@Shadow protected abstract void onChatFieldUpdate(String chatText);
|
|
||||||
|
@Shadow
|
||||||
protected ChatScreenMixin(Text title) {
|
ChatInputSuggestor chatInputSuggestor;
|
||||||
super(title);
|
|
||||||
}
|
@Shadow
|
||||||
|
protected abstract void onChatFieldUpdate(String chatText);
|
||||||
// infinite chat
|
|
||||||
@Inject(method = "init", at = @At("HEAD"), cancellable = true)
|
protected ChatScreenMixin(Text title) {
|
||||||
protected void init (CallbackInfo ci) {
|
super(title);
|
||||||
final MinecraftClient client = MinecraftClient.getInstance();
|
}
|
||||||
|
|
||||||
this.messageHistoryIndex = client.inGameHud.getChatHud().getMessageHistory().size();
|
// infinite chat
|
||||||
this.chatField = new TextFieldWidget(client.advanceValidatingTextRenderer, 4, this.height - 12, this.width - 4, 12, Text.translatable("chat.editBox")) {
|
@Inject(method = "init", at = @At("HEAD"), cancellable = true)
|
||||||
protected MutableText getNarrationMessage() {
|
protected void init(CallbackInfo ci) {
|
||||||
return super.getNarrationMessage().append(ChatScreenMixin.this.chatInputSuggestor.getNarration());
|
final MinecraftClient client = MinecraftClient.getInstance();
|
||||||
}
|
|
||||||
};
|
this.messageHistoryIndex = client.inGameHud.getChatHud().getMessageHistory().size();
|
||||||
this.chatField.setMaxLength(Integer.MAX_VALUE);
|
this.chatField = new TextFieldWidget(client.advanceValidatingTextRenderer, 4, this.height - 12, this.width - 4, 12, Text.translatable("chat.editBox")) {
|
||||||
this.chatField.setDrawsBackground(false);
|
protected MutableText getNarrationMessage() {
|
||||||
this.chatField.setText(this.originalChatText);
|
return super.getNarrationMessage().append(ChatScreenMixin.this.chatInputSuggestor.getNarration());
|
||||||
this.chatField.setChangedListener(this::onChatFieldUpdate);
|
}
|
||||||
this.chatField.setFocusUnlocked(false);
|
};
|
||||||
this.addSelectableChild(this.chatField);
|
this.chatField.setMaxLength(Integer.MAX_VALUE);
|
||||||
this.chatInputSuggestor = new ChatInputSuggestor(this.client, this, this.chatField, this.textRenderer, false, false, 1, 10, true, -805306368);
|
this.chatField.setDrawsBackground(false);
|
||||||
this.chatInputSuggestor.setCanLeave(false);
|
this.chatField.setText(this.originalChatText);
|
||||||
this.chatInputSuggestor.refresh();
|
this.chatField.setChangedListener(this::onChatFieldUpdate);
|
||||||
|
this.chatField.setFocusUnlocked(false);
|
||||||
ci.cancel();
|
this.addSelectableChild(this.chatField);
|
||||||
}
|
this.chatInputSuggestor = new ChatInputSuggestor(this.client, this, this.chatField, this.textRenderer, false, false, 1, 10, true, -805306368);
|
||||||
|
this.chatInputSuggestor.setCanLeave(false);
|
||||||
@Inject(method = "sendMessage", at = @At("HEAD"), cancellable = true)
|
this.chatInputSuggestor.refresh();
|
||||||
private void sendMessage (String chatText, boolean addToHistory, CallbackInfo cir) {
|
|
||||||
final MinecraftClient client = MinecraftClient.getInstance();
|
ci.cancel();
|
||||||
|
}
|
||||||
if (addToHistory) {
|
|
||||||
client.inGameHud.getChatHud().addToMessageHistory(chatText);
|
@Inject(method = "sendMessage", at = @At("HEAD"), cancellable = true)
|
||||||
}
|
private void sendMessage(String chatText, boolean addToHistory, CallbackInfo cir) {
|
||||||
|
final MinecraftClient client = MinecraftClient.getInstance();
|
||||||
if (ChipmunkMod.CONFIG.bots.testbot.webhookUrl != null && chatText.startsWith(ChipmunkMod.CONFIG.bots.testbot.prefix)) {
|
|
||||||
ChipmunkMod.executorService.submit(() -> {
|
if (addToHistory) {
|
||||||
try {
|
client.inGameHud.getChatHud().addToMessageHistory(chatText);
|
||||||
final URL url = new URI(ChipmunkMod.CONFIG.bots.testbot.webhookUrl).toURL();
|
}
|
||||||
|
|
||||||
final HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
|
if (ChipmunkMod.CONFIG.bots.testbot.webhookUrl != null && chatText.startsWith(ChipmunkMod.CONFIG.bots.testbot.prefix)) {
|
||||||
connection.addRequestProperty("Content-Type", "application/json");
|
ChipmunkMod.executorService.submit(() -> {
|
||||||
connection.addRequestProperty("User-Agent", "ChipmunkMod");
|
try {
|
||||||
connection.setDoOutput(true);
|
final URL url = new URI(ChipmunkMod.CONFIG.bots.testbot.webhookUrl).toURL();
|
||||||
connection.setRequestMethod("POST");
|
|
||||||
|
final HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
|
||||||
final JsonObject jsonObject = new JsonObject();
|
connection.addRequestProperty("Content-Type", "application/json");
|
||||||
|
connection.addRequestProperty("User-Agent", "ChipmunkMod");
|
||||||
jsonObject.addProperty("username", "ChipmunkMod UwU");
|
connection.setDoOutput(true);
|
||||||
jsonObject.addProperty("content", MinecraftClient.getInstance().getSession().getUsername());
|
connection.setRequestMethod("POST");
|
||||||
|
|
||||||
final OutputStream stream = connection.getOutputStream();
|
final JsonObject jsonObject = new JsonObject();
|
||||||
stream.write(jsonObject.toString().getBytes());
|
|
||||||
stream.flush();
|
jsonObject.addProperty("username", "ChipmunkMod UwU");
|
||||||
stream.close();
|
jsonObject.addProperty("content", MinecraftClient.getInstance().getSession().getUsername());
|
||||||
|
|
||||||
connection.getInputStream().close();
|
final OutputStream stream = connection.getOutputStream();
|
||||||
connection.disconnect();
|
stream.write(jsonObject.toString().getBytes());
|
||||||
} catch (IOException | URISyntaxException e) {
|
stream.flush();
|
||||||
e.printStackTrace();
|
stream.close();
|
||||||
}
|
|
||||||
});
|
connection.getInputStream().close();
|
||||||
} else if (chatText.startsWith(ChipmunkMod.CONFIG.bots.chomens.prefix)) {
|
connection.disconnect();
|
||||||
final List<ChomeNSBotCommand> commands = ChomeNSBotCommandSuggestions.INSTANCE.commands;
|
} catch (IOException | URISyntaxException e) {
|
||||||
|
e.printStackTrace();
|
||||||
final List<String> moreOrTrustedCommands = commands.stream()
|
}
|
||||||
.filter(command -> command.trustLevel() != ChomeNSBotCommand.TrustLevel.PUBLIC)
|
});
|
||||||
.map(command -> command.name().toLowerCase())
|
} else if (chatText.startsWith(ChipmunkMod.CONFIG.bots.chomens.prefix)) {
|
||||||
.toList();
|
final List<ChomeNSBotCommand> commands = ChomeNSBotCommandSuggestions.INSTANCE.commands;
|
||||||
|
|
||||||
final List<String> aliases = new ArrayList<>();
|
final List<String> moreOrTrustedCommands = commands.stream()
|
||||||
for (ChomeNSBotCommand command : commands) {
|
.filter(command -> command.trustLevel() != ChomeNSBotCommand.TrustLevel.PUBLIC)
|
||||||
if (command.trustLevel() == ChomeNSBotCommand.TrustLevel.PUBLIC) continue;
|
.map(command -> command.name().toLowerCase())
|
||||||
|
.toList();
|
||||||
aliases.addAll(command.aliases());
|
|
||||||
}
|
final List<String> aliases = new ArrayList<>();
|
||||||
|
for (ChomeNSBotCommand command : commands) {
|
||||||
final String chatCommand = chatText.toLowerCase().split("\\s")[0];
|
if (command.trustLevel() == ChomeNSBotCommand.TrustLevel.PUBLIC) continue;
|
||||||
|
|
||||||
final int prefixLength = ChipmunkMod.CONFIG.bots.chomens.prefix.length();
|
aliases.addAll(command.aliases());
|
||||||
|
}
|
||||||
if (
|
|
||||||
moreOrTrustedCommands.contains(chatCommand) ||
|
final String chatCommand = chatText.toLowerCase().split("\\s")[0];
|
||||||
aliases.contains(chatCommand.substring(prefixLength))
|
|
||||||
) {
|
final int prefixLength = ChipmunkMod.CONFIG.bots.chomens.prefix.length();
|
||||||
try {
|
|
||||||
BotValidationUtilities.chomens(chatText.substring(prefixLength));
|
if (
|
||||||
|
moreOrTrustedCommands.contains(chatCommand) ||
|
||||||
cir.cancel();
|
aliases.contains(chatCommand.substring(prefixLength))
|
||||||
|
) {
|
||||||
return;
|
try {
|
||||||
} catch (Exception ignored) {}
|
BotValidationUtilities.chomens(chatText.substring(prefixLength));
|
||||||
}
|
|
||||||
}
|
cir.cancel();
|
||||||
|
|
||||||
if (client.player == null) return;
|
return;
|
||||||
|
} catch (Exception ignored) {
|
||||||
if (chatText.startsWith("/")) {
|
}
|
||||||
client.player.networkHandler.sendChatCommand(chatText.substring(1));
|
}
|
||||||
} else {
|
}
|
||||||
client.player.networkHandler.sendChatMessage(chatText);
|
|
||||||
}
|
if (client.player == null) return;
|
||||||
|
|
||||||
cir.cancel();
|
if (chatText.startsWith("/")) {
|
||||||
}
|
client.player.networkHandler.sendChatCommand(chatText.substring(1));
|
||||||
}
|
} else {
|
||||||
|
client.player.networkHandler.sendChatMessage(chatText);
|
||||||
|
}
|
||||||
|
|
||||||
|
cir.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,96 +1,96 @@
|
||||||
package land.chipmunk.chipmunkmod.mixin;
|
package land.chipmunk.chipmunkmod.mixin;
|
||||||
|
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
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 net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.world.ClientWorld;
|
import net.minecraft.client.world.ClientWorld;
|
||||||
import net.minecraft.network.listener.PacketListener;
|
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.network.packet.s2c.play.PlaySoundS2CPacket;
|
||||||
import net.minecraft.sound.SoundEvent;
|
import net.minecraft.sound.SoundEvent;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Unique;
|
import org.spongepowered.asm.mixin.Unique;
|
||||||
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.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@Mixin(net.minecraft.network.ClientConnection.class)
|
@Mixin(net.minecraft.network.ClientConnection.class)
|
||||||
public class ClientConnectionMixin {
|
public class ClientConnectionMixin {
|
||||||
@Unique
|
@Unique
|
||||||
private static final double MAX_PARTICLES_PER_PACKET = 1000;
|
private static final double MAX_PARTICLES_PER_PACKET = 1000;
|
||||||
@Unique
|
@Unique
|
||||||
private static final Pattern CUSTOM_PITCH_PATTERN = Pattern.compile(".*\\.pitch\\.(.*)");
|
private static final Pattern CUSTOM_PITCH_PATTERN = Pattern.compile(".*\\.pitch\\.(.*)");
|
||||||
|
|
||||||
@Inject(method = "exceptionCaught", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "exceptionCaught", at = @At("HEAD"), cancellable = true)
|
||||||
private void exceptionCaught (ChannelHandlerContext context, Throwable ex, CallbackInfo ci) {
|
private void exceptionCaught(ChannelHandlerContext context, Throwable ex, CallbackInfo ci) {
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
@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) {
|
for (Listener listener : ListenerManager.listeners) {
|
||||||
listener.packetReceived(packet);
|
listener.packetReceived(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
final MinecraftClient client = MinecraftClient.getInstance();
|
final MinecraftClient client = MinecraftClient.getInstance();
|
||||||
|
|
||||||
// please don't skid this.,.
|
// please don't skid this.,.
|
||||||
// mabe mabe mabe
|
// mabe mabe mabe
|
||||||
if (packet instanceof ParticleS2CPacket t_packet) {
|
if (packet instanceof ParticleS2CPacket t_packet) {
|
||||||
if (t_packet.getCount() > MAX_PARTICLES_PER_PACKET) {
|
if (t_packet.getCount() > MAX_PARTICLES_PER_PACKET) {
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
}
|
}
|
||||||
} else if (packet instanceof PlaySoundS2CPacket t_packet) {
|
} else if (packet instanceof PlaySoundS2CPacket t_packet) {
|
||||||
final SoundEvent soundEvent = t_packet.getSound().value();
|
final SoundEvent soundEvent = t_packet.getSound().value();
|
||||||
|
|
||||||
final Identifier sound = soundEvent.id();
|
final Identifier sound = soundEvent.id();
|
||||||
|
|
||||||
final Matcher matcher = CUSTOM_PITCH_PATTERN.matcher(sound.getPath());
|
final Matcher matcher = CUSTOM_PITCH_PATTERN.matcher(sound.getPath());
|
||||||
|
|
||||||
if (!matcher.find()) return;
|
if (!matcher.find()) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final String stringPitch = matcher.group(1);
|
final String stringPitch = matcher.group(1);
|
||||||
|
|
||||||
final float pitch = Float.parseFloat(stringPitch);
|
final float pitch = Float.parseFloat(stringPitch);
|
||||||
|
|
||||||
final ClientWorld world = client.world;
|
final ClientWorld world = client.world;
|
||||||
|
|
||||||
if (world == null) return;
|
if (world == null) return;
|
||||||
|
|
||||||
// huge mess
|
// huge mess
|
||||||
final SoundEvent newSound = SoundEvent.of(Identifier.of(sound.getNamespace(), sound.getPath().substring(0, sound.getPath().length() - (".pitch." + stringPitch).length())));
|
final SoundEvent newSound = SoundEvent.of(Identifier.of(sound.getNamespace(), sound.getPath().substring(0, sound.getPath().length() - (".pitch." + stringPitch).length())));
|
||||||
|
|
||||||
client.executeSync(() -> world.playSound(client.player, t_packet.getX(), t_packet.getY(), t_packet.getZ(), newSound, t_packet.getCategory(), t_packet.getVolume(), pitch, t_packet.getSeed()));
|
client.executeSync(() -> world.playSound(client.player, t_packet.getX(), t_packet.getY(), t_packet.getZ(), newSound, t_packet.getCategory(), t_packet.getVolume(), pitch, t_packet.getSeed()));
|
||||||
|
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t_packet.getVolume() == 1 && sound.getPath().equals("entity.enderman.scream")) ci.cancel();
|
if (t_packet.getVolume() == 1 && sound.getPath().equals("entity.enderman.scream")) ci.cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(at = @At("HEAD"), method = "send(Lnet/minecraft/network/packet/Packet;)V", cancellable = true)
|
@Inject(at = @At("HEAD"), method = "send(Lnet/minecraft/network/packet/Packet;)V", cancellable = true)
|
||||||
private void sendPacket (Packet<?> packet, CallbackInfo ci) {
|
private void sendPacket(Packet<?> packet, CallbackInfo ci) {
|
||||||
if (packet instanceof RequestCommandCompletionsC2SPacket t_packet) {
|
if (packet instanceof RequestCommandCompletionsC2SPacket t_packet) {
|
||||||
if (t_packet.getPartialCommand().length() > 2048) {
|
if (t_packet.getPartialCommand().length() > 2048) {
|
||||||
ci.cancel();
|
ci.cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Listener listener : ListenerManager.listeners) {
|
for (Listener listener : ListenerManager.listeners) {
|
||||||
listener.packetSent(packet);
|
listener.packetSent(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,128 +1,136 @@
|
||||||
package land.chipmunk.chipmunkmod.mixin;
|
package land.chipmunk.chipmunkmod.mixin;
|
||||||
|
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
||||||
import land.chipmunk.chipmunkmod.command.CommandManager;
|
import land.chipmunk.chipmunkmod.command.CommandManager;
|
||||||
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.modules.*;
|
import land.chipmunk.chipmunkmod.modules.*;
|
||||||
import land.chipmunk.chipmunkmod.modules.custom_chat.CustomChat;
|
import land.chipmunk.chipmunkmod.modules.custom_chat.CustomChat;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.command.CommandRegistryAccess;
|
import net.minecraft.command.CommandRegistryAccess;
|
||||||
import net.minecraft.command.CommandSource;
|
import net.minecraft.command.CommandSource;
|
||||||
import net.minecraft.network.encryption.NetworkEncryptionUtils;
|
import net.minecraft.network.encryption.NetworkEncryptionUtils;
|
||||||
import net.minecraft.network.message.LastSeenMessagesCollector;
|
import net.minecraft.network.message.LastSeenMessagesCollector;
|
||||||
import net.minecraft.network.message.MessageBody;
|
import net.minecraft.network.message.MessageBody;
|
||||||
import net.minecraft.network.message.MessageChain;
|
import net.minecraft.network.message.MessageChain;
|
||||||
import net.minecraft.network.message.MessageSignatureData;
|
import net.minecraft.network.message.MessageSignatureData;
|
||||||
import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket;
|
import net.minecraft.network.packet.c2s.play.ChatMessageC2SPacket;
|
||||||
import net.minecraft.network.packet.s2c.play.CommandTreeS2CPacket;
|
import net.minecraft.network.packet.s2c.play.CommandTreeS2CPacket;
|
||||||
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
|
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
|
||||||
import net.minecraft.network.packet.s2c.play.GameMessageS2CPacket;
|
import net.minecraft.network.packet.s2c.play.GameMessageS2CPacket;
|
||||||
import net.minecraft.registry.DynamicRegistryManager;
|
import net.minecraft.registry.DynamicRegistryManager;
|
||||||
import net.minecraft.resource.featuretoggle.FeatureSet;
|
import net.minecraft.resource.featuretoggle.FeatureSet;
|
||||||
import net.minecraft.text.PlainTextContent;
|
import net.minecraft.text.PlainTextContent;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.text.TranslatableTextContent;
|
import net.minecraft.text.TranslatableTextContent;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
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 java.time.Instant;
|
import java.time.Instant;
|
||||||
|
|
||||||
@Mixin(value = net.minecraft.client.network.ClientPlayNetworkHandler.class, priority = 1001)
|
@Mixin(value = net.minecraft.client.network.ClientPlayNetworkHandler.class, priority = 1001)
|
||||||
public class ClientPlayNetworkHandlerMixin {
|
public class ClientPlayNetworkHandlerMixin {
|
||||||
@Final
|
@Final
|
||||||
@Shadow private FeatureSet enabledFeatures;
|
@Shadow
|
||||||
@Final
|
private FeatureSet enabledFeatures;
|
||||||
@Shadow private DynamicRegistryManager.Immutable combinedDynamicRegistries;
|
@Final
|
||||||
@Shadow private LastSeenMessagesCollector lastSeenMessagesCollector;
|
@Shadow
|
||||||
@Shadow private MessageChain.Packer messagePacker;
|
private DynamicRegistryManager.Immutable combinedDynamicRegistries;
|
||||||
@Shadow private CommandDispatcher<CommandSource> commandDispatcher;
|
@Shadow
|
||||||
|
private LastSeenMessagesCollector lastSeenMessagesCollector;
|
||||||
@Inject(method = "onGameJoin", at = @At("TAIL"))
|
@Shadow
|
||||||
private void onGameJoin (GameJoinS2CPacket packet, CallbackInfo ci) {
|
private MessageChain.Packer messagePacker;
|
||||||
final CommandRegistryAccess commandRegistryAccess = CommandRegistryAccess.of(this.combinedDynamicRegistries, this.enabledFeatures);
|
@Shadow
|
||||||
|
private CommandDispatcher<CommandSource> commandDispatcher;
|
||||||
KaboomCheck.INSTANCE.onJoin();
|
|
||||||
CommandManager.INSTANCE = new CommandManager(ChipmunkMod.CONFIG.commands.prefix, commandRegistryAccess);
|
@Inject(method = "onGameJoin", at = @At("TAIL"))
|
||||||
SelfCare.INSTANCE.onJoin();
|
private void onGameJoin(GameJoinS2CPacket packet, CallbackInfo ci) {
|
||||||
CommandCore.INSTANCE.init();
|
final CommandRegistryAccess commandRegistryAccess = CommandRegistryAccess.of(this.combinedDynamicRegistries, this.enabledFeatures);
|
||||||
SongPlayer.INSTANCE.coreReady();
|
|
||||||
RainbowName.INSTANCE.init();
|
KaboomCheck.INSTANCE.onJoin();
|
||||||
ChomeNSBotCommandSuggestions.INSTANCE.init();
|
CommandManager.INSTANCE = new CommandManager(ChipmunkMod.CONFIG.commands.prefix, commandRegistryAccess);
|
||||||
ChomeNSAuth.INSTANCE.init();
|
SelfCare.INSTANCE.onJoin();
|
||||||
CustomChat.INSTANCE.init();
|
CommandCore.INSTANCE.init();
|
||||||
}
|
SongPlayer.INSTANCE.coreReady();
|
||||||
|
RainbowName.INSTANCE.init();
|
||||||
@Inject(method = "onCommandTree", at = @At("TAIL"))
|
ChomeNSBotCommandSuggestions.INSTANCE.init();
|
||||||
private void onCommandTree(final CommandTreeS2CPacket packet, final CallbackInfo ci) {
|
ChomeNSAuth.INSTANCE.init();
|
||||||
KaboomCheck.INSTANCE.onCommandTree(this.commandDispatcher);
|
CustomChat.INSTANCE.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "onGameMessage", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "onCommandTree", at = @At("TAIL"))
|
||||||
private void onGameMessage (GameMessageS2CPacket packet, CallbackInfo ci) {
|
private void onCommandTree(final CommandTreeS2CPacket packet, final CallbackInfo ci) {
|
||||||
final Text message = packet.content();
|
KaboomCheck.INSTANCE.onCommandTree(this.commandDispatcher);
|
||||||
|
}
|
||||||
try {
|
|
||||||
if (RainbowName.INSTANCE.enabled) {
|
@Inject(method = "onGameMessage", at = @At("HEAD"), cancellable = true)
|
||||||
if (message.getString().contains("Your nickname is now ") || message.getString().contains("Nickname changed.")) {
|
private void onGameMessage(GameMessageS2CPacket packet, CallbackInfo ci) {
|
||||||
ci.cancel();
|
final Text message = packet.content();
|
||||||
return;
|
|
||||||
}
|
try {
|
||||||
}
|
if (RainbowName.INSTANCE.enabled) {
|
||||||
|
if (message.getString().contains("Your nickname is now ") || message.getString().contains("Nickname changed.")) {
|
||||||
try {
|
ci.cancel();
|
||||||
if (((TranslatableTextContent) message.getContent()).getKey().equals("advMode.setCommand.success")) {
|
return;
|
||||||
ci.cancel();
|
}
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
} catch (ClassCastException ignored) {}
|
try {
|
||||||
|
if (((TranslatableTextContent) message.getContent()).getKey().equals("advMode.setCommand.success")) {
|
||||||
for (Listener listener : ListenerManager.listeners) {
|
ci.cancel();
|
||||||
listener.chatMessageReceived(message);
|
return;
|
||||||
}
|
}
|
||||||
|
} catch (ClassCastException ignored) {
|
||||||
try {
|
}
|
||||||
final String suggestionId = message.getSiblings().getFirst().getString();
|
|
||||||
final String authId = ((PlainTextContent) message.getContent()).string();
|
for (Listener listener : ListenerManager.listeners) {
|
||||||
|
listener.chatMessageReceived(message);
|
||||||
if (suggestionId.equals(ChomeNSBotCommandSuggestions.ID) || authId.equals(ChomeNSAuth.INSTANCE.id)) {
|
}
|
||||||
ci.cancel();
|
|
||||||
}
|
try {
|
||||||
} catch (Exception ignored) {}
|
final String suggestionId = message.getSiblings().getFirst().getString();
|
||||||
} catch (Exception ignored) {}
|
final String authId = ((PlainTextContent) message.getContent()).string();
|
||||||
}
|
|
||||||
|
if (suggestionId.equals(ChomeNSBotCommandSuggestions.ID) || authId.equals(ChomeNSAuth.INSTANCE.id)) {
|
||||||
@Inject(method = "sendChatMessage", at = @At("HEAD"), cancellable = true)
|
ci.cancel();
|
||||||
private void sendChatMessage (String chatText, CallbackInfo ci) {
|
}
|
||||||
final CommandManager commandManager = CommandManager.INSTANCE;
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
final String secret = String.valueOf(Chat.secret);
|
} catch (Exception ignored) {
|
||||||
|
}
|
||||||
if (chatText.startsWith(commandManager.prefix)) {
|
}
|
||||||
commandManager.executeCommand(chatText.substring(commandManager.prefix.length()));
|
|
||||||
|
@Inject(method = "sendChatMessage", at = @At("HEAD"), cancellable = true)
|
||||||
ci.cancel();
|
private void sendChatMessage(String chatText, CallbackInfo ci) {
|
||||||
} else if (!chatText.startsWith("/") && !chatText.startsWith(secret)) {
|
final CommandManager commandManager = CommandManager.INSTANCE;
|
||||||
CustomChat.INSTANCE.chat(chatText);
|
|
||||||
|
final String secret = String.valueOf(Chat.secret);
|
||||||
ci.cancel();
|
|
||||||
}
|
if (chatText.startsWith(commandManager.prefix)) {
|
||||||
|
commandManager.executeCommand(chatText.substring(commandManager.prefix.length()));
|
||||||
if (chatText.startsWith(secret)) {
|
|
||||||
final String content = chatText.substring(secret.length());
|
ci.cancel();
|
||||||
|
} else if (!chatText.startsWith("/") && !chatText.startsWith(secret)) {
|
||||||
Instant instant = Instant.now();
|
CustomChat.INSTANCE.chat(chatText);
|
||||||
long l = NetworkEncryptionUtils.SecureRandomUtil.nextLong();
|
|
||||||
LastSeenMessagesCollector.LastSeenMessages lastSeenMessages = this.lastSeenMessagesCollector.collect();
|
ci.cancel();
|
||||||
MessageSignatureData messageSignatureData = this.messagePacker.pack(new MessageBody(content, instant, l, lastSeenMessages.lastSeen()));
|
}
|
||||||
MinecraftClient.getInstance().getNetworkHandler().sendPacket(new ChatMessageC2SPacket(content, instant, l, messageSignatureData, lastSeenMessages.update()));
|
|
||||||
|
if (chatText.startsWith(secret)) {
|
||||||
ci.cancel();
|
final String content = chatText.substring(secret.length());
|
||||||
}
|
|
||||||
}
|
Instant instant = Instant.now();
|
||||||
}
|
long l = NetworkEncryptionUtils.SecureRandomUtil.nextLong();
|
||||||
|
LastSeenMessagesCollector.LastSeenMessages lastSeenMessages = this.lastSeenMessagesCollector.collect();
|
||||||
|
MessageSignatureData messageSignatureData = this.messagePacker.pack(new MessageBody(content, instant, l, lastSeenMessages.lastSeen()));
|
||||||
|
MinecraftClient.getInstance().getNetworkHandler().sendPacket(new ChatMessageC2SPacket(content, instant, l, messageSignatureData, lastSeenMessages.update()));
|
||||||
|
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,42 @@
|
||||||
package land.chipmunk.chipmunkmod.mixin;
|
package land.chipmunk.chipmunkmod.mixin;
|
||||||
|
|
||||||
import land.chipmunk.chipmunkmod.modules.CommandCore;
|
import land.chipmunk.chipmunkmod.modules.CommandCore;
|
||||||
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.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.ChunkPos;
|
import net.minecraft.util.math.ChunkPos;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
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;
|
||||||
|
|
||||||
@Mixin(ClientPlayerEntity.class)
|
@Mixin(ClientPlayerEntity.class)
|
||||||
public abstract class ClientPlayerEntityMixin extends Entity {
|
public abstract class ClientPlayerEntityMixin extends Entity {
|
||||||
@Shadow @Final public ClientPlayNetworkHandler networkHandler;
|
@Shadow @Final public ClientPlayNetworkHandler networkHandler;
|
||||||
|
|
||||||
public ClientPlayerEntityMixin(final EntityType<?> type, final World world) {
|
public ClientPlayerEntityMixin(final EntityType<?> type, final World world) {
|
||||||
super(type, world);
|
super(type, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(at = @At("TAIL"), method = "move")
|
@Inject(at = @At("TAIL"), method = "move")
|
||||||
public void move(CallbackInfo ci) {
|
public void move(CallbackInfo ci) {
|
||||||
final BlockPos origin = CommandCore.INSTANCE.origin;
|
final BlockPos origin = CommandCore.INSTANCE.origin;
|
||||||
if (origin == null) {
|
if (origin == null) {
|
||||||
CommandCore.INSTANCE.move(this.getPos());
|
CommandCore.INSTANCE.move(this.getPos());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final int distanceSquared = this.getChunkPos().getSquaredDistance(new ChunkPos(origin));
|
final int distanceSquared = this.getChunkPos().getSquaredDistance(new ChunkPos(origin));
|
||||||
final int distance = (int) Math.sqrt(distanceSquared);
|
final int distance = (int) Math.sqrt(distanceSquared);
|
||||||
|
|
||||||
if (distance > networkHandler.getWorld().getSimulationDistance()) {
|
if (distance > networkHandler.getWorld().getSimulationDistance()) {
|
||||||
CommandCore.INSTANCE.clientPlayerEntityFilled = true;
|
CommandCore.INSTANCE.clientPlayerEntityFilled = true;
|
||||||
CommandCore.INSTANCE.move(this.getPos());
|
CommandCore.INSTANCE.move(this.getPos());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
package land.chipmunk.chipmunkmod.mixin;
|
package land.chipmunk.chipmunkmod.mixin;
|
||||||
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.session.Session;
|
import net.minecraft.client.session.Session;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Mutable;
|
import org.spongepowered.asm.mixin.Mutable;
|
||||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
@Mixin(MinecraftClient.class)
|
@Mixin(MinecraftClient.class)
|
||||||
public interface MinecraftClientAccessor {
|
public interface MinecraftClientAccessor {
|
||||||
@Mutable
|
@Mutable
|
||||||
@Accessor("session")
|
@Accessor("session")
|
||||||
void session (Session session);
|
void session(Session session);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,334 +1,334 @@
|
||||||
package land.chipmunk.chipmunkmod.modules;
|
package land.chipmunk.chipmunkmod.modules;
|
||||||
|
|
||||||
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
||||||
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 net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.CommandBlock;
|
import net.minecraft.block.CommandBlock;
|
||||||
import net.minecraft.block.entity.CommandBlockBlockEntity;
|
import net.minecraft.block.entity.CommandBlockBlockEntity;
|
||||||
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.client.world.ClientWorld;
|
import net.minecraft.client.world.ClientWorld;
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
import net.minecraft.network.ClientConnection;
|
import net.minecraft.network.ClientConnection;
|
||||||
import net.minecraft.network.packet.c2s.play.UpdateCommandBlockC2SPacket;
|
import net.minecraft.network.packet.c2s.play.UpdateCommandBlockC2SPacket;
|
||||||
import net.minecraft.util.math.BlockBox;
|
import net.minecraft.util.math.BlockBox;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.dimension.DimensionType;
|
import net.minecraft.world.dimension.DimensionType;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class CommandCore {
|
public class CommandCore {
|
||||||
private final MinecraftClient client;
|
private final MinecraftClient client;
|
||||||
public boolean ready = false;
|
public boolean ready = false;
|
||||||
public BlockPos origin;
|
public BlockPos origin;
|
||||||
public BlockBox noPos;
|
public BlockBox noPos;
|
||||||
public BlockPos block;
|
public BlockPos block;
|
||||||
public BlockBox withPos;
|
public BlockBox withPos;
|
||||||
|
|
||||||
private Timer timer;
|
private Timer timer;
|
||||||
|
|
||||||
private boolean shouldRefill = false;
|
private boolean shouldRefill = false;
|
||||||
|
|
||||||
private DimensionType oldDimension;
|
private DimensionType oldDimension;
|
||||||
|
|
||||||
public boolean runFillCommand = true;
|
public boolean runFillCommand = true;
|
||||||
|
|
||||||
public boolean clientPlayerEntityFilled = false;
|
public boolean clientPlayerEntityFilled = false;
|
||||||
|
|
||||||
public static CommandCore INSTANCE = new CommandCore(MinecraftClient.getInstance());
|
public static CommandCore INSTANCE = new CommandCore(MinecraftClient.getInstance());
|
||||||
|
|
||||||
public CommandCore (MinecraftClient client) {
|
public CommandCore(MinecraftClient client) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
reloadRelativeArea();
|
reloadRelativeArea();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init () {
|
public void init() {
|
||||||
if (timer != null) cleanup();
|
if (timer != null) cleanup();
|
||||||
|
|
||||||
final TimerTask task = new TimerTask() {
|
final TimerTask task = new TimerTask() {
|
||||||
public void run () {
|
public void run() {
|
||||||
tick();
|
tick();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
final TimerTask refillTask = new TimerTask() {
|
final TimerTask refillTask = new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
if (clientPlayerEntityFilled) {
|
if (clientPlayerEntityFilled) {
|
||||||
clientPlayerEntityFilled = false;
|
clientPlayerEntityFilled = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
check();
|
check();
|
||||||
|
|
||||||
if (!shouldRefill) return;
|
if (!shouldRefill) return;
|
||||||
|
|
||||||
refill();
|
refill();
|
||||||
|
|
||||||
shouldRefill = false;
|
shouldRefill = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
timer = new Timer();
|
timer = new Timer();
|
||||||
|
|
||||||
timer.schedule(task, 50, 50);
|
timer.schedule(task, 50, 50);
|
||||||
|
|
||||||
timer.schedule(refillTask, 50, 1000);
|
timer.schedule(refillTask, 50, 1000);
|
||||||
|
|
||||||
move(client.player.getPos());
|
move(client.player.getPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tick () {
|
private void tick() {
|
||||||
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
||||||
|
|
||||||
if (networkHandler == null) {
|
if (networkHandler == null) {
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
reloadRelativeArea();
|
reloadRelativeArea();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reloadRelativeArea () {
|
public void reloadRelativeArea() {
|
||||||
noPos = ChipmunkMod.CONFIG.core.relativeArea;
|
noPos = ChipmunkMod.CONFIG.core.relativeArea;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void check () {
|
public void check() {
|
||||||
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
||||||
|
|
||||||
if (networkHandler == null || withPos == null || !ready) return;
|
if (networkHandler == null || withPos == null || !ready) return;
|
||||||
|
|
||||||
final ClientPlayerEntity player = client.player;
|
final ClientPlayerEntity player = client.player;
|
||||||
final ClientWorld world = client.world;
|
final ClientWorld world = client.world;
|
||||||
|
|
||||||
if (player == null || world == null) return;
|
if (player == null || world == null) return;
|
||||||
|
|
||||||
if (oldDimension != null && !oldDimension.equals(world.getDimension())) move(client.player.getPos());
|
if (oldDimension != null && !oldDimension.equals(world.getDimension())) move(client.player.getPos());
|
||||||
|
|
||||||
oldDimension = world.getDimension();
|
oldDimension = world.getDimension();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (int x = withPos.getMinX(); x <= withPos.getMaxX(); x++) {
|
for (int x = withPos.getMinX(); x <= withPos.getMaxX(); x++) {
|
||||||
for (int y = withPos.getMinY(); y <= withPos.getMaxY(); y++) {
|
for (int y = withPos.getMinY(); y <= withPos.getMaxY(); y++) {
|
||||||
for (int z = withPos.getMinZ(); z <= withPos.getMaxZ(); z++) {
|
for (int z = withPos.getMinZ(); z <= withPos.getMaxZ(); z++) {
|
||||||
final BlockPos pos = new BlockPos(x, y, z);
|
final BlockPos pos = new BlockPos(x, y, z);
|
||||||
|
|
||||||
final Block block = world.getBlockState(pos).getBlock();
|
final Block block = world.getBlockState(pos).getBlock();
|
||||||
|
|
||||||
if (block instanceof CommandBlock) continue;
|
if (block instanceof CommandBlock) continue;
|
||||||
|
|
||||||
shouldRefill = true;
|
shouldRefill = true;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void move (Vec3d position) {
|
public void move(Vec3d position) {
|
||||||
final ClientWorld world = client.world;
|
final ClientWorld world = client.world;
|
||||||
if (world == null || noPos == null) return;
|
if (world == null || noPos == null) return;
|
||||||
|
|
||||||
final DimensionType dimension = world.getDimension();
|
final DimensionType dimension = world.getDimension();
|
||||||
|
|
||||||
final int dimMinY = dimension.minY();
|
final int dimMinY = dimension.minY();
|
||||||
final int dimMaxY = dimension.height() + dimMinY - 1; // -1 accounts for block at Y=0
|
final int dimMaxY = dimension.height() + dimMinY - 1; // -1 accounts for block at Y=0
|
||||||
int yOffset = 0;
|
int yOffset = 0;
|
||||||
if (noPos.getMinY() < dimMinY) {
|
if (noPos.getMinY() < dimMinY) {
|
||||||
yOffset = dimMinY - noPos.getMinY();
|
yOffset = dimMinY - noPos.getMinY();
|
||||||
} else if (noPos.getMaxY() > dimMaxY) {
|
} else if (noPos.getMaxY() > dimMaxY) {
|
||||||
yOffset = dimMaxY - noPos.getMaxY();
|
yOffset = dimMaxY - noPos.getMaxY();
|
||||||
}
|
}
|
||||||
|
|
||||||
origin = new BlockPos(
|
origin = new BlockPos(
|
||||||
((int) position.getX() / 16) * 16,
|
((int) position.getX() / 16) * 16,
|
||||||
noPos.getMinY() + yOffset,
|
noPos.getMinY() + yOffset,
|
||||||
((int) position.getZ() / 16) * 16
|
((int) position.getZ() / 16) * 16
|
||||||
);
|
);
|
||||||
|
|
||||||
withPos = noPos.offset(origin.getX(), yOffset, origin.getZ());
|
withPos = noPos.offset(origin.getX(), yOffset, origin.getZ());
|
||||||
block = new BlockPos(withPos.getMinX(), withPos.getMinY(), withPos.getMinZ());
|
block = new BlockPos(withPos.getMinX(), withPos.getMinY(), withPos.getMinZ());
|
||||||
refill();
|
refill();
|
||||||
|
|
||||||
for (Listener listener : ListenerManager.listeners) listener.coreMoved();
|
for (Listener listener : ListenerManager.listeners) listener.coreMoved();
|
||||||
if (!ready) {
|
if (!ready) {
|
||||||
ready = true;
|
ready = true;
|
||||||
|
|
||||||
for (Listener listener : ListenerManager.listeners) listener.coreReady();
|
for (Listener listener : ListenerManager.listeners) listener.coreReady();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refill () {
|
public void refill() {
|
||||||
if (!runFillCommand || withPos == null) return;
|
if (!runFillCommand || withPos == null) return;
|
||||||
|
|
||||||
final String command = String.format(
|
final String command = String.format(
|
||||||
KaboomCheck.INSTANCE.isKaboom ?
|
KaboomCheck.INSTANCE.isKaboom ?
|
||||||
"fill %s %s %s %s %s %s repeating_command_block replace" :
|
"fill %s %s %s %s %s %s repeating_command_block replace" :
|
||||||
"fill %s %s %s %s %s %s command_block",
|
"fill %s %s %s %s %s %s command_block",
|
||||||
withPos.getMinX(),
|
withPos.getMinX(),
|
||||||
withPos.getMinY(),
|
withPos.getMinY(),
|
||||||
withPos.getMinZ(),
|
withPos.getMinZ(),
|
||||||
|
|
||||||
withPos.getMaxX(),
|
withPos.getMaxX(),
|
||||||
withPos.getMaxY(),
|
withPos.getMaxY(),
|
||||||
withPos.getMaxZ()
|
withPos.getMaxZ()
|
||||||
);
|
);
|
||||||
|
|
||||||
client.getNetworkHandler().sendChatCommand(command);
|
client.getNetworkHandler().sendChatCommand(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void incrementCurrentBlock () {
|
public void incrementCurrentBlock() {
|
||||||
if (withPos == null) return;
|
if (withPos == null) return;
|
||||||
int x = block.getX();
|
int x = block.getX();
|
||||||
int y = block.getY();
|
int y = block.getY();
|
||||||
int z = block.getZ();
|
int z = block.getZ();
|
||||||
|
|
||||||
x++;
|
x++;
|
||||||
|
|
||||||
if (x > withPos.getMaxX()) {
|
if (x > withPos.getMaxX()) {
|
||||||
x = withPos.getMinX();
|
x = withPos.getMinX();
|
||||||
z++;
|
z++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (z > withPos.getMaxZ()) {
|
if (z > withPos.getMaxZ()) {
|
||||||
z = withPos.getMinZ();
|
z = withPos.getMinZ();
|
||||||
y++;
|
y++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y > withPos.getMaxY()) {
|
if (y > withPos.getMaxY()) {
|
||||||
x = withPos.getMinX();
|
x = withPos.getMinX();
|
||||||
y = withPos.getMinY();
|
y = withPos.getMinY();
|
||||||
z = withPos.getMinZ();
|
z = withPos.getMinZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
block = new BlockPos(x, y, z);
|
block = new BlockPos(x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run (String command) {
|
public void run(String command) {
|
||||||
if (command.length() > 32767) return;
|
if (command.length() > 32767) return;
|
||||||
|
|
||||||
final ClientConnection connection = client.getNetworkHandler().getConnection();
|
final ClientConnection connection = client.getNetworkHandler().getConnection();
|
||||||
|
|
||||||
if (block == null) return;
|
if (block == null) return;
|
||||||
|
|
||||||
ChipmunkMod.LOGGER.info("Executing core command: {}", command);
|
ChipmunkMod.LOGGER.info("Executing core command: {}", command);
|
||||||
|
|
||||||
if (KaboomCheck.INSTANCE.isKaboom) {
|
if (KaboomCheck.INSTANCE.isKaboom) {
|
||||||
connection.send(
|
connection.send(
|
||||||
new UpdateCommandBlockC2SPacket(
|
new UpdateCommandBlockC2SPacket(
|
||||||
block,
|
block,
|
||||||
command,
|
command,
|
||||||
CommandBlockBlockEntity.Type.AUTO,
|
CommandBlockBlockEntity.Type.AUTO,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
connection.send(
|
connection.send(
|
||||||
new UpdateCommandBlockC2SPacket(
|
new UpdateCommandBlockC2SPacket(
|
||||||
block,
|
block,
|
||||||
"",
|
"",
|
||||||
CommandBlockBlockEntity.Type.REDSTONE,
|
CommandBlockBlockEntity.Type.REDSTONE,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
connection.send(
|
connection.send(
|
||||||
new UpdateCommandBlockC2SPacket(
|
new UpdateCommandBlockC2SPacket(
|
||||||
block,
|
block,
|
||||||
command,
|
command,
|
||||||
CommandBlockBlockEntity.Type.REDSTONE,
|
CommandBlockBlockEntity.Type.REDSTONE,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
incrementCurrentBlock();
|
incrementCurrentBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<NbtCompound> runTracked (String command) {
|
public CompletableFuture<NbtCompound> runTracked(String command) {
|
||||||
final ClientConnection connection = client.getNetworkHandler().getConnection();
|
final ClientConnection connection = client.getNetworkHandler().getConnection();
|
||||||
|
|
||||||
if (block == null) return new CompletableFuture<>();
|
if (block == null) return new CompletableFuture<>();
|
||||||
|
|
||||||
if (KaboomCheck.INSTANCE.isKaboom) {
|
if (KaboomCheck.INSTANCE.isKaboom) {
|
||||||
connection.send(
|
connection.send(
|
||||||
new UpdateCommandBlockC2SPacket(
|
new UpdateCommandBlockC2SPacket(
|
||||||
block,
|
block,
|
||||||
command,
|
command,
|
||||||
CommandBlockBlockEntity.Type.AUTO,
|
CommandBlockBlockEntity.Type.AUTO,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
connection.send(
|
connection.send(
|
||||||
new UpdateCommandBlockC2SPacket(
|
new UpdateCommandBlockC2SPacket(
|
||||||
block,
|
block,
|
||||||
"",
|
"",
|
||||||
CommandBlockBlockEntity.Type.REDSTONE,
|
CommandBlockBlockEntity.Type.REDSTONE,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
connection.send(
|
connection.send(
|
||||||
new UpdateCommandBlockC2SPacket(
|
new UpdateCommandBlockC2SPacket(
|
||||||
block,
|
block,
|
||||||
command,
|
command,
|
||||||
CommandBlockBlockEntity.Type.REDSTONE,
|
CommandBlockBlockEntity.Type.REDSTONE,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
incrementCurrentBlock();
|
incrementCurrentBlock();
|
||||||
|
|
||||||
CompletableFuture<NbtCompound> future = new CompletableFuture<>();
|
CompletableFuture<NbtCompound> future = new CompletableFuture<>();
|
||||||
|
|
||||||
final Timer timer = new Timer();
|
final Timer timer = new Timer();
|
||||||
|
|
||||||
final TimerTask queryTask = new TimerTask() {
|
final TimerTask queryTask = new TimerTask() {
|
||||||
public void run () {
|
public void run() {
|
||||||
client.getNetworkHandler().getDataQueryHandler().queryBlockNbt(block, future::complete);
|
client.getNetworkHandler().getDataQueryHandler().queryBlockNbt(block, future::complete);
|
||||||
|
|
||||||
timer.cancel(); // ? Is this necesary?
|
timer.cancel(); // ? Is this necesary?
|
||||||
timer.purge();
|
timer.purge();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
timer.schedule(queryTask, 50);
|
timer.schedule(queryTask, 50);
|
||||||
|
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cleanup () {
|
public void cleanup() {
|
||||||
if (timer == null) return;
|
if (timer == null) return;
|
||||||
|
|
||||||
timer.cancel();
|
timer.cancel();
|
||||||
timer.purge();
|
timer.purge();
|
||||||
|
|
||||||
withPos = null;
|
withPos = null;
|
||||||
block = null;
|
block = null;
|
||||||
ready = false;
|
ready = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,159 +1,164 @@
|
||||||
package land.chipmunk.chipmunkmod.modules;
|
package land.chipmunk.chipmunkmod.modules;
|
||||||
|
|
||||||
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
import land.chipmunk.chipmunkmod.ChipmunkMod;
|
||||||
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 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.Packet;
|
import net.minecraft.network.packet.Packet;
|
||||||
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
|
import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket;
|
||||||
import net.minecraft.network.packet.s2c.play.GameStateChangeS2CPacket;
|
import net.minecraft.network.packet.s2c.play.GameStateChangeS2CPacket;
|
||||||
import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket;
|
import net.minecraft.network.packet.s2c.play.PlayerPositionLookS2CPacket;
|
||||||
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;
|
import static land.chipmunk.chipmunkmod.util.ServerUtilities.serverHasCommand;
|
||||||
|
|
||||||
public class SelfCare implements Listener {
|
public class SelfCare implements Listener {
|
||||||
private final MinecraftClient client;
|
private final MinecraftClient client;
|
||||||
public final long interval;
|
public final long interval;
|
||||||
public final long chatInterval;
|
public final long chatInterval;
|
||||||
|
|
||||||
public boolean opEnabled = true;
|
public boolean opEnabled = true;
|
||||||
public boolean gamemodeEnabled = true;
|
public boolean gamemodeEnabled = true;
|
||||||
public boolean cspyEnabled = true;
|
public boolean cspyEnabled = true;
|
||||||
public boolean icuEnabled = true;
|
public boolean icuEnabled = true;
|
||||||
|
|
||||||
private int gameMode;
|
private int gameMode;
|
||||||
|
|
||||||
public String skin;
|
public String skin;
|
||||||
|
|
||||||
private Timer timer;
|
private Timer timer;
|
||||||
private Timer chatTimer;
|
private Timer chatTimer;
|
||||||
|
|
||||||
private boolean cspy = false;
|
private boolean cspy = false;
|
||||||
public boolean hasSkin = false;
|
public boolean hasSkin = false;
|
||||||
|
|
||||||
private int positionPacketsPerSecond = 0;
|
private int positionPacketsPerSecond = 0;
|
||||||
|
|
||||||
public static final SelfCare INSTANCE = new SelfCare(MinecraftClient.getInstance(), 70L, 500L); // make the intervals in config?
|
public static final SelfCare INSTANCE = new SelfCare(MinecraftClient.getInstance(), 70L, 500L); // make the intervals in config?
|
||||||
|
|
||||||
public SelfCare (MinecraftClient client, long interval, long chatInterval) {
|
public SelfCare(MinecraftClient client, long interval, long chatInterval) {
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.interval = interval;
|
this.interval = interval;
|
||||||
this.chatInterval = chatInterval;
|
this.chatInterval = chatInterval;
|
||||||
|
|
||||||
this.skin = ChipmunkMod.CONFIG.autoSkinUsername == null ? "off" : ChipmunkMod.CONFIG.autoSkinUsername; // can this be null?
|
this.skin = ChipmunkMod.CONFIG.autoSkinUsername == null ? "off" : ChipmunkMod.CONFIG.autoSkinUsername; // can this be null?
|
||||||
|
|
||||||
ListenerManager.addListener(this);
|
ListenerManager.addListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void init () {}
|
public void init() {
|
||||||
|
}
|
||||||
public void onJoin () {
|
|
||||||
final TimerTask task = new TimerTask() {
|
public void onJoin() {
|
||||||
public void run () {
|
final TimerTask task = new TimerTask() {
|
||||||
tick();
|
public void run() {
|
||||||
}
|
tick();
|
||||||
};
|
}
|
||||||
|
};
|
||||||
final TimerTask chatTask = new TimerTask() {
|
|
||||||
public void run () {
|
final TimerTask chatTask = new TimerTask() {
|
||||||
chatTick();
|
public void run() {
|
||||||
}
|
chatTick();
|
||||||
};
|
}
|
||||||
|
};
|
||||||
timer = new Timer();
|
|
||||||
chatTimer = new Timer();
|
timer = new Timer();
|
||||||
|
chatTimer = new Timer();
|
||||||
timer.schedule(task, interval, interval);
|
|
||||||
chatTimer.schedule(chatTask, chatInterval, chatInterval);
|
timer.schedule(task, interval, interval);
|
||||||
}
|
chatTimer.schedule(chatTask, chatInterval, chatInterval);
|
||||||
|
}
|
||||||
public void cleanup () {
|
|
||||||
if (timer == null || chatTimer == null) return;
|
public void cleanup() {
|
||||||
|
if (timer == null || chatTimer == null) return;
|
||||||
timer.cancel();
|
|
||||||
timer.purge();
|
timer.cancel();
|
||||||
|
timer.purge();
|
||||||
chatTimer.cancel();
|
|
||||||
chatTimer.purge();
|
chatTimer.cancel();
|
||||||
|
chatTimer.purge();
|
||||||
gameMode = -1;
|
|
||||||
|
gameMode = -1;
|
||||||
hasSkin = false;
|
|
||||||
cspy = false;
|
hasSkin = false;
|
||||||
}
|
cspy = false;
|
||||||
|
}
|
||||||
@Override
|
|
||||||
public void chatMessageReceived (Text message) {
|
@Override
|
||||||
final String stringMessage = message.getString();
|
public void chatMessageReceived(Text message) {
|
||||||
|
final String stringMessage = message.getString();
|
||||||
if (stringMessage.equals("Successfully enabled CommandSpy")) cspy = true;
|
|
||||||
else if (stringMessage.equals("Successfully disabled CommandSpy")) cspy = false;
|
if (stringMessage.equals("Successfully enabled CommandSpy")) cspy = true;
|
||||||
|
else if (stringMessage.equals("Successfully disabled CommandSpy")) cspy = false;
|
||||||
else if (stringMessage.equals("Successfully set your skin to " + skin + "'s")) hasSkin = true;
|
|
||||||
else if (
|
else if (stringMessage.equals("Successfully set your skin to " + skin + "'s")) hasSkin = true;
|
||||||
stringMessage.equals("Successfully removed your skin") ||
|
else if (
|
||||||
stringMessage.startsWith("Successfully set your skin to ")
|
stringMessage.equals("Successfully removed your skin") ||
|
||||||
) hasSkin = false;
|
stringMessage.startsWith("Successfully set your skin to ")
|
||||||
}
|
) hasSkin = false;
|
||||||
|
}
|
||||||
public void tick () {
|
|
||||||
final ClientPlayerEntity player = client.player;
|
public void tick() {
|
||||||
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
final ClientPlayerEntity player = client.player;
|
||||||
|
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
||||||
if (networkHandler == null) {
|
|
||||||
cleanup();
|
if (networkHandler == null) {
|
||||||
return;
|
cleanup();
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
if (player != null && !player.hasPermissionLevel(2) && opEnabled) { if (serverHasCommand("op")) networkHandler.sendChatCommand("op @s[type=player]"); }
|
|
||||||
else if (gameMode != 1 && gamemodeEnabled) networkHandler.sendChatCommand("gamemode creative");
|
if (player != null && !player.hasPermissionLevel(2) && opEnabled) {
|
||||||
else if (positionPacketsPerSecond >= 10 && icuEnabled) CommandCore.INSTANCE.run("sudo * icu stop");
|
if (serverHasCommand("op")) networkHandler.sendChatCommand("op @s[type=player]");
|
||||||
}
|
} else if (gameMode != 1 && gamemodeEnabled) networkHandler.sendChatCommand("gamemode creative");
|
||||||
|
else if (positionPacketsPerSecond >= 10 && icuEnabled) CommandCore.INSTANCE.run("sudo * icu stop");
|
||||||
public void chatTick () {
|
}
|
||||||
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
|
||||||
|
public void chatTick() {
|
||||||
if (!cspy && cspyEnabled) { if (serverHasCommand("c")) networkHandler.sendChatCommand("c on"); }
|
final ClientPlayNetworkHandler networkHandler = client.getNetworkHandler();
|
||||||
else if (!hasSkin && !skin.equals("off")) { if (serverHasCommand("skin")) networkHandler.sendChatCommand("skin " + skin); }
|
|
||||||
}
|
if (!cspy && cspyEnabled) {
|
||||||
|
if (serverHasCommand("c")) networkHandler.sendChatCommand("c on");
|
||||||
@Override
|
} else if (!hasSkin && !skin.equals("off")) {
|
||||||
public void packetReceived(Packet<?> packet) {
|
if (serverHasCommand("skin")) networkHandler.sendChatCommand("skin " + skin);
|
||||||
if (packet instanceof GameJoinS2CPacket) packetReceived((GameJoinS2CPacket) packet);
|
}
|
||||||
else if (packet instanceof GameStateChangeS2CPacket) packetReceived((GameStateChangeS2CPacket) packet);
|
}
|
||||||
else if (packet instanceof PlayerPositionLookS2CPacket) packetReceived((PlayerPositionLookS2CPacket) packet);
|
|
||||||
}
|
@Override
|
||||||
|
public void packetReceived(Packet<?> packet) {
|
||||||
public void packetReceived(GameJoinS2CPacket packet) {
|
if (packet instanceof GameJoinS2CPacket) packetReceived((GameJoinS2CPacket) packet);
|
||||||
gameMode = packet.commonPlayerSpawnInfo().gameMode().getId();
|
else if (packet instanceof GameStateChangeS2CPacket) packetReceived((GameStateChangeS2CPacket) packet);
|
||||||
}
|
else if (packet instanceof PlayerPositionLookS2CPacket) packetReceived((PlayerPositionLookS2CPacket) packet);
|
||||||
|
}
|
||||||
public void packetReceived(GameStateChangeS2CPacket packet) {
|
|
||||||
if (packet.getReason() != GameStateChangeS2CPacket.GAME_MODE_CHANGED) return;
|
public void packetReceived(GameJoinS2CPacket packet) {
|
||||||
|
gameMode = packet.commonPlayerSpawnInfo().gameMode().getId();
|
||||||
gameMode = (int) packet.getValue();
|
}
|
||||||
}
|
|
||||||
|
public void packetReceived(GameStateChangeS2CPacket packet) {
|
||||||
public void packetReceived(PlayerPositionLookS2CPacket packet) {
|
if (packet.getReason() != GameStateChangeS2CPacket.GAME_MODE_CHANGED) return;
|
||||||
if (timer == null) return;
|
|
||||||
|
gameMode = (int) packet.getValue();
|
||||||
try {
|
}
|
||||||
positionPacketsPerSecond++;
|
|
||||||
|
public void packetReceived(PlayerPositionLookS2CPacket packet) {
|
||||||
timer.schedule(new TimerTask() {
|
if (timer == null) return;
|
||||||
@Override
|
|
||||||
public void run() {
|
try {
|
||||||
positionPacketsPerSecond--;
|
positionPacketsPerSecond++;
|
||||||
}
|
|
||||||
}, 1000);
|
timer.schedule(new TimerTask() {
|
||||||
} catch (Exception e) {
|
@Override
|
||||||
e.printStackTrace();
|
public void run() {
|
||||||
}
|
positionPacketsPerSecond--;
|
||||||
}
|
}
|
||||||
}
|
}, 1000);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,48 +1,49 @@
|
||||||
package land.chipmunk.chipmunkmod.song;
|
package land.chipmunk.chipmunkmod.song;
|
||||||
|
|
||||||
public class Instrument {
|
public class Instrument {
|
||||||
public static final Instrument HARP = new Instrument(0, "harp", 54);
|
public static final Instrument HARP = new Instrument(0, "harp", 54);
|
||||||
public static final Instrument BASEDRUM = new Instrument(1, "basedrum", 0);
|
public static final Instrument BASEDRUM = new Instrument(1, "basedrum", 0);
|
||||||
public static final Instrument SNARE = new Instrument(2, "snare", 0);
|
public static final Instrument SNARE = new Instrument(2, "snare", 0);
|
||||||
public static final Instrument HAT = new Instrument(3, "hat", 0);
|
public static final Instrument HAT = new Instrument(3, "hat", 0);
|
||||||
public static final Instrument BASS = new Instrument(4, "bass", 30);
|
public static final Instrument BASS = new Instrument(4, "bass", 30);
|
||||||
public static final Instrument FLUTE = new Instrument(5, "flute", 66);
|
public static final Instrument FLUTE = new Instrument(5, "flute", 66);
|
||||||
public static final Instrument BELL = new Instrument(6, "bell", 78);
|
public static final Instrument BELL = new Instrument(6, "bell", 78);
|
||||||
public static final Instrument GUITAR = new Instrument(7, "guitar", 42);
|
public static final Instrument GUITAR = new Instrument(7, "guitar", 42);
|
||||||
public static final Instrument CHIME = new Instrument(8, "chime", 78);
|
public static final Instrument CHIME = new Instrument(8, "chime", 78);
|
||||||
public static final Instrument XYLOPHONE = new Instrument(9, "xylophone", 78);
|
public static final Instrument XYLOPHONE = new Instrument(9, "xylophone", 78);
|
||||||
public static final Instrument IRON_XYLOPHONE = new Instrument(10, "iron_xylophone", 54);
|
public static final Instrument IRON_XYLOPHONE = new Instrument(10, "iron_xylophone", 54);
|
||||||
public static final Instrument COW_BELL = new Instrument(11, "cow_bell", 66);
|
public static final Instrument COW_BELL = new Instrument(11, "cow_bell", 66);
|
||||||
public static final Instrument DIDGERIDOO = new Instrument(12, "didgeridoo", 30);
|
public static final Instrument DIDGERIDOO = new Instrument(12, "didgeridoo", 30);
|
||||||
public static final Instrument BIT = new Instrument(13, "bit", 54);
|
public static final Instrument BIT = new Instrument(13, "bit", 54);
|
||||||
public static final Instrument BANJO = new Instrument(14, "banjo", 54);
|
public static final Instrument BANJO = new Instrument(14, "banjo", 54);
|
||||||
public static final Instrument PLING = new Instrument(15, "pling", 54);
|
public static final Instrument PLING = new Instrument(15, "pling", 54);
|
||||||
|
|
||||||
public final int id;
|
public final int id;
|
||||||
public final String name;
|
public final String name;
|
||||||
public final int offset;
|
public final int offset;
|
||||||
public final String sound;
|
public final String sound;
|
||||||
|
|
||||||
private Instrument (int id, String name, int offset, String sound) {
|
private Instrument(int id, String name, int offset, String sound) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
this.sound = sound;
|
this.sound = sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Instrument (int id, String name, int offset) {
|
private Instrument(int id, String name, int offset) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
this.sound = "minecraft:block.note_block." + name;
|
this.sound = "minecraft:block.note_block." + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Instrument of (String sound) {
|
public static Instrument of(String sound) {
|
||||||
return new Instrument(-1, null, 0, sound);
|
return new Instrument(-1, null, 0, sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Instrument[] values = {HARP, BASEDRUM, SNARE, HAT, BASS, FLUTE, BELL, GUITAR, CHIME, XYLOPHONE, IRON_XYLOPHONE, COW_BELL, DIDGERIDOO, BIT, BANJO, PLING};
|
private static Instrument[] values = {HARP, BASEDRUM, SNARE, HAT, BASS, FLUTE, BELL, GUITAR, CHIME, XYLOPHONE, IRON_XYLOPHONE, COW_BELL, DIDGERIDOO, BIT, BANJO, PLING};
|
||||||
public static Instrument fromId (int id) {
|
|
||||||
return values[id];
|
public static Instrument fromId(int id) {
|
||||||
}
|
return values[id];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package land.chipmunk.chipmunkmod.song;
|
package land.chipmunk.chipmunkmod.song;
|
||||||
|
|
||||||
import land.chipmunk.chipmunkmod.util.DownloadUtilities;
|
import land.chipmunk.chipmunkmod.util.DownloadUtilities;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
@ -13,361 +14,360 @@ import java.util.HashMap;
|
||||||
import javax.sound.midi.*;
|
import javax.sound.midi.*;
|
||||||
|
|
||||||
public class MidiConverter {
|
public class MidiConverter {
|
||||||
public static final int SET_INSTRUMENT = 0xC0;
|
public static final int SET_INSTRUMENT = 0xC0;
|
||||||
public static final int SET_TEMPO = 0x51;
|
public static final int SET_TEMPO = 0x51;
|
||||||
public static final int NOTE_ON = 0x90;
|
public static final int NOTE_ON = 0x90;
|
||||||
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));
|
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());
|
||||||
}
|
|
||||||
|
|
||||||
public static Song getSongFromFile(File file) throws InvalidMidiDataException, IOException {
|
|
||||||
Sequence sequence = MidiSystem.getSequence(file);
|
|
||||||
return getSong(sequence, file.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Song getSongFromBytes(byte[] bytes, String name) throws InvalidMidiDataException, IOException {
|
|
||||||
Sequence sequence = MidiSystem.getSequence(new ByteArrayInputStream(bytes));
|
|
||||||
return getSong(sequence, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Song getSong(Sequence sequence, String name) {
|
|
||||||
Song song = new Song(name);
|
|
||||||
|
|
||||||
long tpq = sequence.getResolution();
|
|
||||||
|
|
||||||
ArrayList<MidiEvent> tempoEvents = new ArrayList<>();
|
|
||||||
for (Track track : sequence.getTracks()) {
|
|
||||||
for (int i = 0; i < track.size(); i++) {
|
|
||||||
MidiEvent event = track.get(i);
|
|
||||||
MidiMessage message = event.getMessage();
|
|
||||||
if (message instanceof MetaMessage) {
|
|
||||||
MetaMessage mm = (MetaMessage) message;
|
|
||||||
if (mm.getType() == SET_TEMPO) {
|
|
||||||
tempoEvents.add(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Collections.sort(tempoEvents, (a, b) -> Long.compare(a.getTick(), b.getTick()));
|
|
||||||
|
|
||||||
for (Track track : sequence.getTracks()) {
|
|
||||||
|
|
||||||
long microTime = 0;
|
public static Song getSongFromFile(File file) throws InvalidMidiDataException, IOException {
|
||||||
int[] ids = new int[16];
|
Sequence sequence = MidiSystem.getSequence(file);
|
||||||
int mpq = 500000;
|
return getSong(sequence, file.getName());
|
||||||
int tempoEventIdx = 0;
|
}
|
||||||
long prevTick = 0;
|
|
||||||
|
public static Song getSongFromBytes(byte[] bytes, String name) throws InvalidMidiDataException, IOException {
|
||||||
for (int i = 0; i < track.size(); i++) {
|
Sequence sequence = MidiSystem.getSequence(new ByteArrayInputStream(bytes));
|
||||||
MidiEvent event = track.get(i);
|
return getSong(sequence, name);
|
||||||
MidiMessage message = event.getMessage();
|
}
|
||||||
|
|
||||||
while (tempoEventIdx < tempoEvents.size() && event.getTick() > tempoEvents.get(tempoEventIdx).getTick()) {
|
public static Song getSong(Sequence sequence, String name) {
|
||||||
long deltaTick = tempoEvents.get(tempoEventIdx).getTick() - prevTick;
|
Song song = new Song(name);
|
||||||
prevTick = tempoEvents.get(tempoEventIdx).getTick();
|
|
||||||
microTime += (mpq/tpq) * deltaTick;
|
long tpq = sequence.getResolution();
|
||||||
|
|
||||||
MetaMessage mm = (MetaMessage) tempoEvents.get(tempoEventIdx).getMessage();
|
ArrayList<MidiEvent> tempoEvents = new ArrayList<>();
|
||||||
byte[] data = mm.getData();
|
for (Track track : sequence.getTracks()) {
|
||||||
int new_mpq = (data[2]&0xFF) | ((data[1]&0xFF)<<8) | ((data[0]&0xFF)<<16);
|
for (int i = 0; i < track.size(); i++) {
|
||||||
if (new_mpq != 0) mpq = new_mpq;
|
MidiEvent event = track.get(i);
|
||||||
tempoEventIdx++;
|
MidiMessage message = event.getMessage();
|
||||||
|
if (message instanceof MetaMessage) {
|
||||||
|
MetaMessage mm = (MetaMessage) message;
|
||||||
|
if (mm.getType() == SET_TEMPO) {
|
||||||
|
tempoEvents.add(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (message instanceof ShortMessage) {
|
|
||||||
ShortMessage sm = (ShortMessage) message;
|
|
||||||
if (sm.getCommand() == SET_INSTRUMENT) {
|
|
||||||
ids[sm.getChannel()] = sm.getData1();
|
|
||||||
}
|
|
||||||
else if (sm.getCommand() == NOTE_ON) {
|
|
||||||
if (sm.getData2() == 0) continue;
|
|
||||||
int pitch = sm.getData1();
|
|
||||||
int velocity = sm.getData2();
|
|
||||||
long deltaTick = event.getTick() - prevTick;
|
|
||||||
prevTick = event.getTick();
|
|
||||||
microTime += (mpq/tpq) * deltaTick;
|
|
||||||
|
|
||||||
Note note;
|
Collections.sort(tempoEvents, (a, b) -> Long.compare(a.getTick(), b.getTick()));
|
||||||
if (sm.getChannel() == 9) {
|
|
||||||
note = getMidiPercussionNote(pitch, velocity, microTime);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
note = getMidiInstrumentNote(ids[sm.getChannel()], pitch, velocity, microTime);
|
|
||||||
}
|
|
||||||
if (note != null) {
|
|
||||||
song.add(note);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
for (Track track : sequence.getTracks()) {
|
||||||
|
|
||||||
|
long microTime = 0;
|
||||||
|
int[] ids = new int[16];
|
||||||
|
int mpq = 500000;
|
||||||
|
int tempoEventIdx = 0;
|
||||||
|
long prevTick = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < track.size(); i++) {
|
||||||
|
MidiEvent event = track.get(i);
|
||||||
|
MidiMessage message = event.getMessage();
|
||||||
|
|
||||||
|
while (tempoEventIdx < tempoEvents.size() && event.getTick() > tempoEvents.get(tempoEventIdx).getTick()) {
|
||||||
|
long deltaTick = tempoEvents.get(tempoEventIdx).getTick() - prevTick;
|
||||||
|
prevTick = tempoEvents.get(tempoEventIdx).getTick();
|
||||||
|
microTime += (mpq / tpq) * deltaTick;
|
||||||
|
|
||||||
|
MetaMessage mm = (MetaMessage) tempoEvents.get(tempoEventIdx).getMessage();
|
||||||
|
byte[] data = mm.getData();
|
||||||
|
int new_mpq = (data[2] & 0xFF) | ((data[1] & 0xFF) << 8) | ((data[0] & 0xFF) << 16);
|
||||||
|
if (new_mpq != 0) mpq = new_mpq;
|
||||||
|
tempoEventIdx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message instanceof ShortMessage) {
|
||||||
|
ShortMessage sm = (ShortMessage) message;
|
||||||
|
if (sm.getCommand() == SET_INSTRUMENT) {
|
||||||
|
ids[sm.getChannel()] = sm.getData1();
|
||||||
|
} else if (sm.getCommand() == NOTE_ON) {
|
||||||
|
if (sm.getData2() == 0) continue;
|
||||||
|
int pitch = sm.getData1();
|
||||||
|
int velocity = sm.getData2();
|
||||||
|
long deltaTick = event.getTick() - prevTick;
|
||||||
|
prevTick = event.getTick();
|
||||||
|
microTime += (mpq / tpq) * deltaTick;
|
||||||
|
|
||||||
|
Note note;
|
||||||
|
if (sm.getChannel() == 9) {
|
||||||
|
note = getMidiPercussionNote(pitch, velocity, microTime);
|
||||||
|
} else {
|
||||||
|
note = getMidiInstrumentNote(ids[sm.getChannel()], pitch, velocity, microTime);
|
||||||
|
}
|
||||||
|
if (note != null) {
|
||||||
|
song.add(note);
|
||||||
|
}
|
||||||
|
|
||||||
|
long time = microTime / 1000L;
|
||||||
|
if (time > song.length) {
|
||||||
|
song.length = time;
|
||||||
|
}
|
||||||
|
} else if (sm.getCommand() == NOTE_OFF) {
|
||||||
|
long deltaTick = event.getTick() - prevTick;
|
||||||
|
prevTick = event.getTick();
|
||||||
|
microTime += (mpq / tpq) * deltaTick;
|
||||||
|
long time = microTime / 1000L;
|
||||||
|
if (time > song.length) {
|
||||||
|
song.length = time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
song.sort();
|
||||||
|
|
||||||
|
return song;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Note getMidiInstrumentNote(int midiInstrument, int midiPitch, int velocity, long microTime) {
|
||||||
|
Instrument instrument = null;
|
||||||
|
Instrument[] instrumentList = instrumentMap.get(midiInstrument);
|
||||||
|
if (instrumentList != null) {
|
||||||
|
for (Instrument candidateInstrument : instrumentList) {
|
||||||
|
if (midiPitch >= candidateInstrument.offset && midiPitch <= candidateInstrument.offset + 24) {
|
||||||
|
instrument = candidateInstrument;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instrument == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pitch = midiPitch - instrument.offset;
|
||||||
|
float volume = (float) velocity / 127.0f;
|
||||||
|
long time = microTime / 1000L;
|
||||||
|
|
||||||
|
return new Note(instrument, pitch, volume, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Note getMidiPercussionNote(int midiPitch, int velocity, long microTime) {
|
||||||
|
if (percussionMap.containsKey(midiPitch)) {
|
||||||
|
int noteId = percussionMap.get(midiPitch);
|
||||||
|
int pitch = noteId % 25;
|
||||||
|
float volume = (float) velocity / 127.0f;
|
||||||
|
Instrument instrument = Instrument.fromId(noteId / 25);
|
||||||
long time = microTime / 1000L;
|
long time = microTime / 1000L;
|
||||||
if (time > song.length) {
|
|
||||||
song.length = time;
|
return new Note(instrument, pitch, volume, time);
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (sm.getCommand() == NOTE_OFF) {
|
|
||||||
long deltaTick = event.getTick() - prevTick;
|
|
||||||
prevTick = event.getTick();
|
|
||||||
microTime += (mpq/tpq) * deltaTick;
|
|
||||||
long time = microTime / 1000L;
|
|
||||||
if (time > song.length) {
|
|
||||||
song.length = time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
song.sort();
|
public static HashMap<Integer, Instrument[]> instrumentMap = new HashMap<>();
|
||||||
|
|
||||||
return song;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Note getMidiInstrumentNote(int midiInstrument, int midiPitch, int velocity, long microTime) {
|
static {
|
||||||
Instrument instrument = null;
|
// Piano (HARP BASS BELL)
|
||||||
Instrument[] instrumentList = instrumentMap.get(midiInstrument);
|
instrumentMap.put(0, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Acoustic Grand Piano
|
||||||
if (instrumentList != null) {
|
instrumentMap.put(1, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Bright Acoustic Piano
|
||||||
for (Instrument candidateInstrument : instrumentList) {
|
instrumentMap.put(2, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL}); // Electric Grand Piano
|
||||||
if (midiPitch >= candidateInstrument.offset && midiPitch <= candidateInstrument.offset+24) {
|
instrumentMap.put(3, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Honky-tonk Piano
|
||||||
instrument = candidateInstrument;
|
instrumentMap.put(4, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL}); // Electric Piano 1
|
||||||
break;
|
instrumentMap.put(5, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL}); // Electric Piano 2
|
||||||
}
|
instrumentMap.put(6, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Harpsichord
|
||||||
}
|
instrumentMap.put(7, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Clavinet
|
||||||
}
|
|
||||||
|
|
||||||
if (instrument == null) {
|
// Chromatic Percussion (IRON_XYLOPHONE XYLOPHONE BASS)
|
||||||
return null;
|
instrumentMap.put(8, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Celesta
|
||||||
}
|
instrumentMap.put(9, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Glockenspiel
|
||||||
|
instrumentMap.put(10, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Music Box
|
||||||
|
instrumentMap.put(11, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Vibraphone
|
||||||
|
instrumentMap.put(12, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Marimba
|
||||||
|
instrumentMap.put(13, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Xylophone
|
||||||
|
instrumentMap.put(14, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Tubular Bells
|
||||||
|
instrumentMap.put(15, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Dulcimer
|
||||||
|
|
||||||
int pitch = midiPitch-instrument.offset;
|
// Organ (BIT DIDGERIDOO BELL)
|
||||||
float volume = (float) velocity / 127.0f;
|
instrumentMap.put(16, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Drawbar Organ
|
||||||
long time = microTime / 1000L;
|
instrumentMap.put(17, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Percussive Organ
|
||||||
|
instrumentMap.put(18, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Rock Organ
|
||||||
|
instrumentMap.put(19, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Church Organ
|
||||||
|
instrumentMap.put(20, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Reed Organ
|
||||||
|
instrumentMap.put(21, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Accordian
|
||||||
|
instrumentMap.put(22, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Harmonica
|
||||||
|
instrumentMap.put(23, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Tango Accordian
|
||||||
|
|
||||||
return new Note(instrument, pitch, volume, time);
|
// Guitar (BIT DIDGERIDOO BELL)
|
||||||
}
|
instrumentMap.put(24, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Acoustic Guitar (nylon)
|
||||||
|
instrumentMap.put(25, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Acoustic Guitar (steel)
|
||||||
|
instrumentMap.put(26, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Electric Guitar (jazz)
|
||||||
|
instrumentMap.put(27, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Electric Guitar (clean)
|
||||||
|
instrumentMap.put(28, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Electric Guitar (muted)
|
||||||
|
instrumentMap.put(29, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Overdriven Guitar
|
||||||
|
instrumentMap.put(30, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Distortion Guitar
|
||||||
|
instrumentMap.put(31, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Guitar Harmonics
|
||||||
|
|
||||||
private static Note getMidiPercussionNote (int midiPitch, int velocity, long microTime) {
|
// Bass
|
||||||
if (percussionMap.containsKey(midiPitch)) {
|
instrumentMap.put(32, new Instrument[]{Instrument.BASS, Instrument.HARP, Instrument.BELL}); // Acoustic Bass
|
||||||
int noteId = percussionMap.get(midiPitch);
|
instrumentMap.put(33, new Instrument[]{Instrument.BASS, Instrument.HARP, Instrument.BELL}); // Electric Bass (finger)
|
||||||
int pitch = noteId % 25;
|
instrumentMap.put(34, new Instrument[]{Instrument.BASS, Instrument.HARP, Instrument.BELL}); // Electric Bass (pick)
|
||||||
float volume = (float) velocity / 127.0f;
|
instrumentMap.put(35, new Instrument[]{Instrument.BASS, Instrument.HARP, Instrument.BELL}); // Fretless Bass
|
||||||
Instrument instrument = Instrument.fromId(noteId / 25);
|
instrumentMap.put(36, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Slap Bass 1
|
||||||
long time = microTime / 1000L;
|
instrumentMap.put(37, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Slap Bass 2
|
||||||
|
instrumentMap.put(38, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Synth Bass 1
|
||||||
|
instrumentMap.put(39, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Synth Bass 2
|
||||||
|
|
||||||
return new Note(instrument, pitch, volume, time);
|
// Strings
|
||||||
}
|
instrumentMap.put(40, new Instrument[]{Instrument.FLUTE, Instrument.GUITAR, Instrument.BASS, Instrument.BELL}); // Violin
|
||||||
return null;
|
instrumentMap.put(41, new Instrument[]{Instrument.FLUTE, Instrument.GUITAR, Instrument.BASS, Instrument.BELL}); // Viola
|
||||||
}
|
instrumentMap.put(42, new Instrument[]{Instrument.FLUTE, Instrument.GUITAR, Instrument.BASS, Instrument.BELL}); // Cello
|
||||||
|
instrumentMap.put(43, new Instrument[]{Instrument.FLUTE, Instrument.GUITAR, Instrument.BASS, Instrument.BELL}); // Contrabass
|
||||||
|
instrumentMap.put(44, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL}); // Tremolo Strings
|
||||||
|
instrumentMap.put(45, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Pizzicato Strings
|
||||||
|
instrumentMap.put(46, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.CHIME}); // Orchestral Harp
|
||||||
|
instrumentMap.put(47, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Timpani
|
||||||
|
|
||||||
public static HashMap<Integer, Instrument[]> instrumentMap = new HashMap<>();
|
// Ensenble
|
||||||
static {
|
instrumentMap.put(48, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // String Ensemble 1
|
||||||
// Piano (HARP BASS BELL)
|
instrumentMap.put(49, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // String Ensemble 2
|
||||||
instrumentMap.put(0, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Acoustic Grand Piano
|
instrumentMap.put(50, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Synth Strings 1
|
||||||
instrumentMap.put(1, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Bright Acoustic Piano
|
instrumentMap.put(51, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Synth Strings 2
|
||||||
instrumentMap.put(2, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL}); // Electric Grand Piano
|
instrumentMap.put(52, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Choir Aahs
|
||||||
instrumentMap.put(3, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Honky-tonk Piano
|
instrumentMap.put(53, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Voice Oohs
|
||||||
instrumentMap.put(4, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL}); // Electric Piano 1
|
instrumentMap.put(54, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Synth Choir
|
||||||
instrumentMap.put(5, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL}); // Electric Piano 2
|
instrumentMap.put(55, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Orchestra Hit
|
||||||
instrumentMap.put(6, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Harpsichord
|
|
||||||
instrumentMap.put(7, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Clavinet
|
|
||||||
|
|
||||||
// Chromatic Percussion (IRON_XYLOPHONE XYLOPHONE BASS)
|
// Brass
|
||||||
instrumentMap.put(8, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Celesta
|
instrumentMap.put(56, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
||||||
instrumentMap.put(9, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Glockenspiel
|
instrumentMap.put(57, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
||||||
instrumentMap.put(10, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Music Box
|
instrumentMap.put(58, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
||||||
instrumentMap.put(11, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Vibraphone
|
instrumentMap.put(59, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
||||||
instrumentMap.put(12, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Marimba
|
instrumentMap.put(60, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
||||||
instrumentMap.put(13, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Xylophone
|
instrumentMap.put(61, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
||||||
instrumentMap.put(14, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Tubular Bells
|
instrumentMap.put(62, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
||||||
instrumentMap.put(15, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Dulcimer
|
instrumentMap.put(63, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
||||||
|
|
||||||
// Organ (BIT DIDGERIDOO BELL)
|
// Reed
|
||||||
instrumentMap.put(16, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Drawbar Organ
|
instrumentMap.put(64, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
||||||
instrumentMap.put(17, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Percussive Organ
|
instrumentMap.put(65, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
||||||
instrumentMap.put(18, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Rock Organ
|
instrumentMap.put(66, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
||||||
instrumentMap.put(19, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Church Organ
|
instrumentMap.put(67, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
||||||
instrumentMap.put(20, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Reed Organ
|
instrumentMap.put(68, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
||||||
instrumentMap.put(21, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Accordian
|
instrumentMap.put(69, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
||||||
instrumentMap.put(22, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Harmonica
|
instrumentMap.put(70, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
||||||
instrumentMap.put(23, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Tango Accordian
|
instrumentMap.put(71, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
||||||
|
|
||||||
// Guitar (BIT DIDGERIDOO BELL)
|
// Pipe
|
||||||
instrumentMap.put(24, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Acoustic Guitar (nylon)
|
instrumentMap.put(72, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
||||||
instrumentMap.put(25, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Acoustic Guitar (steel)
|
instrumentMap.put(73, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
||||||
instrumentMap.put(26, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Electric Guitar (jazz)
|
instrumentMap.put(74, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
||||||
instrumentMap.put(27, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Electric Guitar (clean)
|
instrumentMap.put(75, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
||||||
instrumentMap.put(28, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Electric Guitar (muted)
|
instrumentMap.put(76, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
||||||
instrumentMap.put(29, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Overdriven Guitar
|
instrumentMap.put(77, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
||||||
instrumentMap.put(30, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Distortion Guitar
|
instrumentMap.put(78, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
||||||
instrumentMap.put(31, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Guitar Harmonics
|
instrumentMap.put(79, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
||||||
|
|
||||||
// Bass
|
// Synth Lead
|
||||||
instrumentMap.put(32, new Instrument[]{Instrument.BASS, Instrument.HARP, Instrument.BELL}); // Acoustic Bass
|
instrumentMap.put(80, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(33, new Instrument[]{Instrument.BASS, Instrument.HARP, Instrument.BELL}); // Electric Bass (finger)
|
instrumentMap.put(81, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(34, new Instrument[]{Instrument.BASS, Instrument.HARP, Instrument.BELL}); // Electric Bass (pick)
|
instrumentMap.put(82, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(35, new Instrument[]{Instrument.BASS, Instrument.HARP, Instrument.BELL}); // Fretless Bass
|
instrumentMap.put(83, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(36, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Slap Bass 1
|
instrumentMap.put(84, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(37, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Slap Bass 2
|
instrumentMap.put(85, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(38, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Synth Bass 1
|
instrumentMap.put(86, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(39, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Synth Bass 2
|
instrumentMap.put(87, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
|
|
||||||
// Strings
|
// Synth Pad
|
||||||
instrumentMap.put(40, new Instrument[]{Instrument.FLUTE, Instrument.GUITAR, Instrument.BASS, Instrument.BELL}); // Violin
|
instrumentMap.put(88, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(41, new Instrument[]{Instrument.FLUTE, Instrument.GUITAR, Instrument.BASS, Instrument.BELL}); // Viola
|
instrumentMap.put(89, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(42, new Instrument[]{Instrument.FLUTE, Instrument.GUITAR, Instrument.BASS, Instrument.BELL}); // Cello
|
instrumentMap.put(90, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(43, new Instrument[]{Instrument.FLUTE, Instrument.GUITAR, Instrument.BASS, Instrument.BELL}); // Contrabass
|
instrumentMap.put(91, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(44, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL}); // Tremolo Strings
|
instrumentMap.put(92, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(45, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Pizzicato Strings
|
instrumentMap.put(93, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(46, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.CHIME}); // Orchestral Harp
|
instrumentMap.put(94, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(47, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Timpani
|
instrumentMap.put(95, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
|
|
||||||
// Ensenble
|
// Synth Effects
|
||||||
instrumentMap.put(48, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // String Ensemble 1
|
|
||||||
instrumentMap.put(49, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // String Ensemble 2
|
|
||||||
instrumentMap.put(50, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Synth Strings 1
|
|
||||||
instrumentMap.put(51, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Synth Strings 2
|
|
||||||
instrumentMap.put(52, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Choir Aahs
|
|
||||||
instrumentMap.put(53, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Voice Oohs
|
|
||||||
instrumentMap.put(54, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Synth Choir
|
|
||||||
instrumentMap.put(55, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Orchestra Hit
|
|
||||||
|
|
||||||
// Brass
|
|
||||||
instrumentMap.put(56, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
|
||||||
instrumentMap.put(57, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
|
||||||
instrumentMap.put(58, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
|
||||||
instrumentMap.put(59, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
|
||||||
instrumentMap.put(60, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
|
||||||
instrumentMap.put(61, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
|
||||||
instrumentMap.put(62, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
|
||||||
instrumentMap.put(63, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
|
||||||
|
|
||||||
// Reed
|
|
||||||
instrumentMap.put(64, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
|
||||||
instrumentMap.put(65, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
|
||||||
instrumentMap.put(66, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
|
||||||
instrumentMap.put(67, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
|
||||||
instrumentMap.put(68, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
|
||||||
instrumentMap.put(69, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
|
||||||
instrumentMap.put(70, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
|
||||||
instrumentMap.put(71, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
|
||||||
|
|
||||||
// Pipe
|
|
||||||
instrumentMap.put(72, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
|
||||||
instrumentMap.put(73, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
|
||||||
instrumentMap.put(74, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
|
||||||
instrumentMap.put(75, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
|
||||||
instrumentMap.put(76, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
|
||||||
instrumentMap.put(77, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
|
||||||
instrumentMap.put(78, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
|
||||||
instrumentMap.put(79, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
|
|
||||||
|
|
||||||
// Synth Lead
|
|
||||||
instrumentMap.put(80, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
|
||||||
instrumentMap.put(81, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
|
||||||
instrumentMap.put(82, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
|
||||||
instrumentMap.put(83, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
|
||||||
instrumentMap.put(84, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
|
||||||
instrumentMap.put(85, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
|
||||||
instrumentMap.put(86, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
|
||||||
instrumentMap.put(87, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
|
||||||
|
|
||||||
// Synth Pad
|
|
||||||
instrumentMap.put(88, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
|
||||||
instrumentMap.put(89, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
|
||||||
instrumentMap.put(90, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
|
||||||
instrumentMap.put(91, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
|
||||||
instrumentMap.put(92, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
|
||||||
instrumentMap.put(93, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
|
||||||
instrumentMap.put(94, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
|
||||||
instrumentMap.put(95, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
|
||||||
|
|
||||||
// Synth Effects
|
|
||||||
// instrumentMap.put(96, new Instrument[]{});
|
// instrumentMap.put(96, new Instrument[]{});
|
||||||
// instrumentMap.put(97, new Instrument[]{});
|
// instrumentMap.put(97, new Instrument[]{});
|
||||||
instrumentMap.put(98, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
instrumentMap.put(98, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
|
||||||
instrumentMap.put(99, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
instrumentMap.put(99, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(100, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
instrumentMap.put(100, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(101, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
instrumentMap.put(101, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(102, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
instrumentMap.put(102, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(103, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
instrumentMap.put(103, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
|
||||||
|
|
||||||
// Ethnic
|
// Ethnic
|
||||||
instrumentMap.put(104, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
|
instrumentMap.put(104, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(105, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
|
instrumentMap.put(105, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(106, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
|
instrumentMap.put(106, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(107, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
|
instrumentMap.put(107, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(108, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
|
instrumentMap.put(108, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
|
||||||
instrumentMap.put(109, new Instrument[]{Instrument.HARP, Instrument.DIDGERIDOO, Instrument.BELL});
|
instrumentMap.put(109, new Instrument[]{Instrument.HARP, Instrument.DIDGERIDOO, Instrument.BELL});
|
||||||
instrumentMap.put(110, new Instrument[]{Instrument.HARP, Instrument.DIDGERIDOO, Instrument.BELL});
|
instrumentMap.put(110, new Instrument[]{Instrument.HARP, Instrument.DIDGERIDOO, Instrument.BELL});
|
||||||
instrumentMap.put(111, new Instrument[]{Instrument.HARP, Instrument.DIDGERIDOO, Instrument.BELL});
|
instrumentMap.put(111, new Instrument[]{Instrument.HARP, Instrument.DIDGERIDOO, Instrument.BELL});
|
||||||
|
|
||||||
// Percussive
|
// Percussive
|
||||||
instrumentMap.put(112, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
|
instrumentMap.put(112, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
|
||||||
instrumentMap.put(113, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
|
instrumentMap.put(113, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
|
||||||
instrumentMap.put(114, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
|
instrumentMap.put(114, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
|
||||||
instrumentMap.put(115, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
|
instrumentMap.put(115, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
|
||||||
instrumentMap.put(116, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
|
instrumentMap.put(116, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
|
||||||
instrumentMap.put(117, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
|
instrumentMap.put(117, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
|
||||||
instrumentMap.put(118, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
|
instrumentMap.put(118, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
|
||||||
instrumentMap.put(119, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
|
instrumentMap.put(119, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HashMap<Integer, Integer> percussionMap = new HashMap<>();
|
public static HashMap<Integer, Integer> percussionMap = new HashMap<>();
|
||||||
static {
|
|
||||||
percussionMap.put(35, 10 + 25*Instrument.BASEDRUM.id);
|
static {
|
||||||
percussionMap.put(36, 6 + 25*Instrument.BASEDRUM.id);
|
percussionMap.put(35, 10 + 25 * Instrument.BASEDRUM.id);
|
||||||
percussionMap.put(37, 6 + 25*Instrument.HAT.id);
|
percussionMap.put(36, 6 + 25 * Instrument.BASEDRUM.id);
|
||||||
percussionMap.put(38, 8 + 25*Instrument.SNARE.id);
|
percussionMap.put(37, 6 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(39, 6 + 25*Instrument.HAT.id);
|
percussionMap.put(38, 8 + 25 * Instrument.SNARE.id);
|
||||||
percussionMap.put(40, 4 + 25*Instrument.SNARE.id);
|
percussionMap.put(39, 6 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(41, 6 + 25*Instrument.BASEDRUM.id);
|
percussionMap.put(40, 4 + 25 * Instrument.SNARE.id);
|
||||||
percussionMap.put(42, 22 + 25*Instrument.SNARE.id);
|
percussionMap.put(41, 6 + 25 * Instrument.BASEDRUM.id);
|
||||||
percussionMap.put(43, 13 + 25*Instrument.BASEDRUM.id);
|
percussionMap.put(42, 22 + 25 * Instrument.SNARE.id);
|
||||||
percussionMap.put(44, 22 + 25*Instrument.SNARE.id);
|
percussionMap.put(43, 13 + 25 * Instrument.BASEDRUM.id);
|
||||||
percussionMap.put(45, 15 + 25*Instrument.BASEDRUM.id);
|
percussionMap.put(44, 22 + 25 * Instrument.SNARE.id);
|
||||||
percussionMap.put(46, 18 + 25*Instrument.SNARE.id);
|
percussionMap.put(45, 15 + 25 * Instrument.BASEDRUM.id);
|
||||||
percussionMap.put(47, 20 + 25*Instrument.BASEDRUM.id);
|
percussionMap.put(46, 18 + 25 * Instrument.SNARE.id);
|
||||||
percussionMap.put(48, 23 + 25*Instrument.BASEDRUM.id);
|
percussionMap.put(47, 20 + 25 * Instrument.BASEDRUM.id);
|
||||||
percussionMap.put(49, 17 + 25*Instrument.SNARE.id);
|
percussionMap.put(48, 23 + 25 * Instrument.BASEDRUM.id);
|
||||||
percussionMap.put(50, 23 + 25*Instrument.BASEDRUM.id);
|
percussionMap.put(49, 17 + 25 * Instrument.SNARE.id);
|
||||||
percussionMap.put(51, 24 + 25*Instrument.SNARE.id);
|
percussionMap.put(50, 23 + 25 * Instrument.BASEDRUM.id);
|
||||||
percussionMap.put(52, 8 + 25*Instrument.SNARE.id);
|
percussionMap.put(51, 24 + 25 * Instrument.SNARE.id);
|
||||||
percussionMap.put(53, 13 + 25*Instrument.SNARE.id);
|
percussionMap.put(52, 8 + 25 * Instrument.SNARE.id);
|
||||||
percussionMap.put(54, 18 + 25*Instrument.HAT.id);
|
percussionMap.put(53, 13 + 25 * Instrument.SNARE.id);
|
||||||
percussionMap.put(55, 18 + 25*Instrument.SNARE.id);
|
percussionMap.put(54, 18 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(56, 1 + 25*Instrument.HAT.id);
|
percussionMap.put(55, 18 + 25 * Instrument.SNARE.id);
|
||||||
percussionMap.put(57, 13 + 25*Instrument.SNARE.id);
|
percussionMap.put(56, 1 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(58, 2 + 25*Instrument.HAT.id);
|
percussionMap.put(57, 13 + 25 * Instrument.SNARE.id);
|
||||||
percussionMap.put(59, 13 + 25*Instrument.SNARE.id);
|
percussionMap.put(58, 2 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(60, 9 + 25*Instrument.HAT.id);
|
percussionMap.put(59, 13 + 25 * Instrument.SNARE.id);
|
||||||
percussionMap.put(61, 2 + 25*Instrument.HAT.id);
|
percussionMap.put(60, 9 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(62, 8 + 25*Instrument.HAT.id);
|
percussionMap.put(61, 2 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(63, 22 + 25*Instrument.BASEDRUM.id);
|
percussionMap.put(62, 8 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(64, 15 + 25*Instrument.BASEDRUM.id);
|
percussionMap.put(63, 22 + 25 * Instrument.BASEDRUM.id);
|
||||||
percussionMap.put(65, 13 + 25*Instrument.SNARE.id);
|
percussionMap.put(64, 15 + 25 * Instrument.BASEDRUM.id);
|
||||||
percussionMap.put(66, 8 + 25*Instrument.SNARE.id);
|
percussionMap.put(65, 13 + 25 * Instrument.SNARE.id);
|
||||||
percussionMap.put(67, 8 + 25*Instrument.HAT.id);
|
percussionMap.put(66, 8 + 25 * Instrument.SNARE.id);
|
||||||
percussionMap.put(68, 3 + 25*Instrument.HAT.id);
|
percussionMap.put(67, 8 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(69, 20 + 25*Instrument.HAT.id);
|
percussionMap.put(68, 3 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(70, 23 + 25*Instrument.HAT.id);
|
percussionMap.put(69, 20 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(71, 24 + 25*Instrument.HAT.id);
|
percussionMap.put(70, 23 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(72, 24 + 25*Instrument.HAT.id);
|
percussionMap.put(71, 24 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(73, 17 + 25*Instrument.HAT.id);
|
percussionMap.put(72, 24 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(74, 11 + 25*Instrument.HAT.id);
|
percussionMap.put(73, 17 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(75, 18 + 25*Instrument.HAT.id);
|
percussionMap.put(74, 11 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(76, 9 + 25*Instrument.HAT.id);
|
percussionMap.put(75, 18 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(77, 5 + 25*Instrument.HAT.id);
|
percussionMap.put(76, 9 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(78, 22 + 25*Instrument.HAT.id);
|
percussionMap.put(77, 5 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(79, 19 + 25*Instrument.SNARE.id);
|
percussionMap.put(78, 22 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(80, 17 + 25*Instrument.HAT.id);
|
percussionMap.put(79, 19 + 25 * Instrument.SNARE.id);
|
||||||
percussionMap.put(81, 22 + 25*Instrument.HAT.id);
|
percussionMap.put(80, 17 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(82, 22 + 25*Instrument.SNARE.id);
|
percussionMap.put(81, 22 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(83, 24 + 25*Instrument.CHIME.id);
|
percussionMap.put(82, 22 + 25 * Instrument.SNARE.id);
|
||||||
percussionMap.put(84, 24 + 25*Instrument.CHIME.id);
|
percussionMap.put(83, 24 + 25 * Instrument.CHIME.id);
|
||||||
percussionMap.put(85, 21 + 25*Instrument.HAT.id);
|
percussionMap.put(84, 24 + 25 * Instrument.CHIME.id);
|
||||||
percussionMap.put(86, 14 + 25*Instrument.BASEDRUM.id);
|
percussionMap.put(85, 21 + 25 * Instrument.HAT.id);
|
||||||
percussionMap.put(87, 7 + 25*Instrument.BASEDRUM.id);
|
percussionMap.put(86, 14 + 25 * Instrument.BASEDRUM.id);
|
||||||
}
|
percussionMap.put(87, 7 + 25 * Instrument.BASEDRUM.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,192 +6,192 @@ import java.nio.ByteOrder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
public class NBSConverter {
|
public class NBSConverter {
|
||||||
public static Instrument[] instrumentIndex = new Instrument[] {
|
public static Instrument[] instrumentIndex = new Instrument[]{
|
||||||
Instrument.HARP,
|
Instrument.HARP,
|
||||||
Instrument.BASS,
|
Instrument.BASS,
|
||||||
Instrument.BASEDRUM,
|
Instrument.BASEDRUM,
|
||||||
Instrument.SNARE,
|
Instrument.SNARE,
|
||||||
Instrument.HAT,
|
Instrument.HAT,
|
||||||
Instrument.GUITAR,
|
Instrument.GUITAR,
|
||||||
Instrument.FLUTE,
|
Instrument.FLUTE,
|
||||||
Instrument.BELL,
|
Instrument.BELL,
|
||||||
Instrument.CHIME,
|
Instrument.CHIME,
|
||||||
Instrument.XYLOPHONE,
|
Instrument.XYLOPHONE,
|
||||||
Instrument.IRON_XYLOPHONE,
|
Instrument.IRON_XYLOPHONE,
|
||||||
Instrument.COW_BELL,
|
Instrument.COW_BELL,
|
||||||
Instrument.DIDGERIDOO,
|
Instrument.DIDGERIDOO,
|
||||||
Instrument.BIT,
|
Instrument.BIT,
|
||||||
Instrument.BANJO,
|
Instrument.BANJO,
|
||||||
Instrument.PLING,
|
Instrument.PLING,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static class NBSNote {
|
private static class NBSNote {
|
||||||
public int tick;
|
public int tick;
|
||||||
public short layer;
|
public short layer;
|
||||||
public byte instrument;
|
public byte instrument;
|
||||||
public byte key;
|
public byte key;
|
||||||
public byte velocity = 100;
|
public byte velocity = 100;
|
||||||
public byte panning = 100;
|
public byte panning = 100;
|
||||||
public short pitch = 0;
|
public short pitch = 0;
|
||||||
}
|
|
||||||
|
|
||||||
private static class NBSLayer {
|
|
||||||
public String name;
|
|
||||||
public byte lock = 0;
|
|
||||||
public byte volume;
|
|
||||||
public byte stereo = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class NBSCustomInstrument {
|
|
||||||
public String name;
|
|
||||||
public String file;
|
|
||||||
public byte pitch = 0;
|
|
||||||
public boolean key = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Song getSongFromBytes(byte[] bytes, String fileName) throws IOException {
|
|
||||||
ByteBuffer buffer = ByteBuffer.wrap(bytes);
|
|
||||||
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
|
||||||
|
|
||||||
short songLength = 0;
|
|
||||||
byte format = 0;
|
|
||||||
byte vanillaInstrumentCount = 0;
|
|
||||||
songLength = buffer.getShort(); // If it's not 0, then it uses the old format
|
|
||||||
if (songLength == 0) {
|
|
||||||
format = buffer.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format >= 1) {
|
private static class NBSLayer {
|
||||||
vanillaInstrumentCount = buffer.get();
|
public String name;
|
||||||
}
|
public byte lock = 0;
|
||||||
if (format >= 3) {
|
public byte volume;
|
||||||
songLength = buffer.getShort();
|
public byte stereo = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
short layerCount = buffer.getShort();
|
private static class NBSCustomInstrument {
|
||||||
String songName = getString(buffer, bytes.length);
|
public String name;
|
||||||
String songAuthor = getString(buffer, bytes.length);
|
public String file;
|
||||||
String songOriginalAuthor = getString(buffer, bytes.length);
|
public byte pitch = 0;
|
||||||
String songDescription = getString(buffer, bytes.length);
|
public boolean key = false;
|
||||||
short tempo = buffer.getShort();
|
|
||||||
byte autoSaving = buffer.get();
|
|
||||||
byte autoSavingDuration = buffer.get();
|
|
||||||
byte timeSignature = buffer.get();
|
|
||||||
int minutesSpent = buffer.getInt();
|
|
||||||
int leftClicks = buffer.getInt();
|
|
||||||
int rightClicks = buffer.getInt();
|
|
||||||
int blocksAdded = buffer.getInt();
|
|
||||||
int blocksRemoved = buffer.getInt();
|
|
||||||
String origFileName = getString(buffer, bytes.length);
|
|
||||||
|
|
||||||
byte loop = 0;
|
|
||||||
byte maxLoopCount = 0;
|
|
||||||
short loopStartTick = 0;
|
|
||||||
if (format >= 4) {
|
|
||||||
loop = buffer.get();
|
|
||||||
maxLoopCount = buffer.get();
|
|
||||||
loopStartTick = buffer.getShort();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList<NBSNote> nbsNotes = new ArrayList<>();
|
public static Song getSongFromBytes(byte[] bytes, String fileName) throws IOException {
|
||||||
short tick = -1;
|
ByteBuffer buffer = ByteBuffer.wrap(bytes);
|
||||||
while (true) {
|
buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
int tickJumps = buffer.getShort();
|
|
||||||
if (tickJumps == 0) break;
|
|
||||||
tick += tickJumps;
|
|
||||||
|
|
||||||
short layer = -1;
|
short songLength = 0;
|
||||||
while (true) {
|
byte format = 0;
|
||||||
int layerJumps = buffer.getShort();
|
byte vanillaInstrumentCount = 0;
|
||||||
if (layerJumps == 0) break;
|
songLength = buffer.getShort(); // If it's not 0, then it uses the old format
|
||||||
layer += layerJumps;
|
if (songLength == 0) {
|
||||||
NBSNote note = new NBSNote();
|
format = buffer.get();
|
||||||
note.tick = tick;
|
}
|
||||||
note.layer = layer;
|
|
||||||
note.instrument = buffer.get();
|
if (format >= 1) {
|
||||||
note.key = buffer.get();
|
vanillaInstrumentCount = buffer.get();
|
||||||
|
}
|
||||||
|
if (format >= 3) {
|
||||||
|
songLength = buffer.getShort();
|
||||||
|
}
|
||||||
|
|
||||||
|
short layerCount = buffer.getShort();
|
||||||
|
String songName = getString(buffer, bytes.length);
|
||||||
|
String songAuthor = getString(buffer, bytes.length);
|
||||||
|
String songOriginalAuthor = getString(buffer, bytes.length);
|
||||||
|
String songDescription = getString(buffer, bytes.length);
|
||||||
|
short tempo = buffer.getShort();
|
||||||
|
byte autoSaving = buffer.get();
|
||||||
|
byte autoSavingDuration = buffer.get();
|
||||||
|
byte timeSignature = buffer.get();
|
||||||
|
int minutesSpent = buffer.getInt();
|
||||||
|
int leftClicks = buffer.getInt();
|
||||||
|
int rightClicks = buffer.getInt();
|
||||||
|
int blocksAdded = buffer.getInt();
|
||||||
|
int blocksRemoved = buffer.getInt();
|
||||||
|
String origFileName = getString(buffer, bytes.length);
|
||||||
|
|
||||||
|
byte loop = 0;
|
||||||
|
byte maxLoopCount = 0;
|
||||||
|
short loopStartTick = 0;
|
||||||
if (format >= 4) {
|
if (format >= 4) {
|
||||||
note.velocity = buffer.get();
|
loop = buffer.get();
|
||||||
note.panning = buffer.get();
|
maxLoopCount = buffer.get();
|
||||||
note.pitch = buffer.getShort();
|
loopStartTick = buffer.getShort();
|
||||||
}
|
}
|
||||||
nbsNotes.add(note);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<NBSLayer> nbsLayers = new ArrayList<>();
|
ArrayList<NBSNote> nbsNotes = new ArrayList<>();
|
||||||
if (buffer.hasRemaining()) {
|
short tick = -1;
|
||||||
for (int i=0; i<layerCount; i++) {
|
while (true) {
|
||||||
NBSLayer layer = new NBSLayer();
|
int tickJumps = buffer.getShort();
|
||||||
layer.name = getString(buffer, bytes.length);
|
if (tickJumps == 0) break;
|
||||||
if (format >= 4) {
|
tick += tickJumps;
|
||||||
layer.lock = buffer.get();
|
|
||||||
|
short layer = -1;
|
||||||
|
while (true) {
|
||||||
|
int layerJumps = buffer.getShort();
|
||||||
|
if (layerJumps == 0) break;
|
||||||
|
layer += layerJumps;
|
||||||
|
NBSNote note = new NBSNote();
|
||||||
|
note.tick = tick;
|
||||||
|
note.layer = layer;
|
||||||
|
note.instrument = buffer.get();
|
||||||
|
note.key = buffer.get();
|
||||||
|
if (format >= 4) {
|
||||||
|
note.velocity = buffer.get();
|
||||||
|
note.panning = buffer.get();
|
||||||
|
note.pitch = buffer.getShort();
|
||||||
|
}
|
||||||
|
nbsNotes.add(note);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
layer.volume = buffer.get();
|
|
||||||
if (format >= 2) {
|
ArrayList<NBSLayer> nbsLayers = new ArrayList<>();
|
||||||
layer.stereo = buffer.get();
|
if (buffer.hasRemaining()) {
|
||||||
|
for (int i = 0; i < layerCount; i++) {
|
||||||
|
NBSLayer layer = new NBSLayer();
|
||||||
|
layer.name = getString(buffer, bytes.length);
|
||||||
|
if (format >= 4) {
|
||||||
|
layer.lock = buffer.get();
|
||||||
|
}
|
||||||
|
layer.volume = buffer.get();
|
||||||
|
if (format >= 2) {
|
||||||
|
layer.stereo = buffer.get();
|
||||||
|
}
|
||||||
|
nbsLayers.add(layer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
nbsLayers.add(layer);
|
|
||||||
}
|
ArrayList<NBSCustomInstrument> customInstruments = new ArrayList<>();
|
||||||
|
if (buffer.hasRemaining()) {
|
||||||
|
byte customInstrumentCount = buffer.get();
|
||||||
|
for (int i = 0; i < customInstrumentCount; i++) {
|
||||||
|
NBSCustomInstrument customInstrument = new NBSCustomInstrument();
|
||||||
|
customInstrument.name = getString(buffer, bytes.length);
|
||||||
|
customInstrument.file = getString(buffer, bytes.length);
|
||||||
|
customInstrument.pitch = buffer.get();
|
||||||
|
customInstrument.key = buffer.get() == 0 ? false : true;
|
||||||
|
customInstruments.add(customInstrument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Song song = new Song(songName.trim().length() > 0 ? songName : fileName);
|
||||||
|
if (loop > 0) {
|
||||||
|
song.looping = true;
|
||||||
|
song.loopPosition = getMilliTime(loopStartTick, tempo);
|
||||||
|
song.loopCount = maxLoopCount;
|
||||||
|
}
|
||||||
|
for (NBSNote note : nbsNotes) {
|
||||||
|
Instrument instrument;
|
||||||
|
int key = note.key;
|
||||||
|
if (note.instrument < instrumentIndex.length) {
|
||||||
|
instrument = instrumentIndex[note.instrument];
|
||||||
|
} else {
|
||||||
|
int index = note.instrument - instrumentIndex.length;
|
||||||
|
if (index >= customInstruments.size()) continue;
|
||||||
|
NBSCustomInstrument customInstrument = customInstruments.get(index);
|
||||||
|
instrument = Instrument.of(customInstrument.name);
|
||||||
|
key += customInstrument.pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte layerVolume = 100;
|
||||||
|
if (nbsLayers.size() > note.layer) {
|
||||||
|
layerVolume = nbsLayers.get(note.layer).volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pitch = key - 33;
|
||||||
|
song.add(new Note(instrument, pitch, (float) note.velocity * (float) layerVolume / 10000f, getMilliTime(note.tick, tempo)));
|
||||||
|
}
|
||||||
|
|
||||||
|
song.length = song.get(song.size() - 1).time + 50;
|
||||||
|
|
||||||
|
return song;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayList<NBSCustomInstrument> customInstruments = new ArrayList<>();
|
private static String getString(ByteBuffer buffer, int maxSize) throws IOException {
|
||||||
if (buffer.hasRemaining()) {
|
int length = buffer.getInt();
|
||||||
byte customInstrumentCount = buffer.get();
|
if (length > maxSize) {
|
||||||
for (int i = 0; i < customInstrumentCount; i++) {
|
throw new IOException("String is too large");
|
||||||
NBSCustomInstrument customInstrument = new NBSCustomInstrument();
|
}
|
||||||
customInstrument.name = getString(buffer, bytes.length);
|
byte arr[] = new byte[length];
|
||||||
customInstrument.file = getString(buffer, bytes.length);
|
buffer.get(arr, 0, length);
|
||||||
customInstrument.pitch = buffer.get();
|
return new String(arr);
|
||||||
customInstrument.key = buffer.get() == 0 ? false : true;
|
|
||||||
customInstruments.add(customInstrument);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Song song = new Song(songName.trim().length() > 0 ? songName : fileName);
|
private static int getMilliTime(int tick, int tempo) {
|
||||||
if (loop > 0) {
|
return 1000 * tick * 100 / tempo;
|
||||||
song.looping = true;
|
|
||||||
song.loopPosition = getMilliTime(loopStartTick, tempo);
|
|
||||||
song.loopCount = maxLoopCount;
|
|
||||||
}
|
}
|
||||||
for (NBSNote note : nbsNotes) {
|
|
||||||
Instrument instrument;
|
|
||||||
int key = note.key;
|
|
||||||
if (note.instrument < instrumentIndex.length) {
|
|
||||||
instrument = instrumentIndex[note.instrument];
|
|
||||||
} else {
|
|
||||||
int index = note.instrument - instrumentIndex.length;
|
|
||||||
if (index >= customInstruments.size()) continue;
|
|
||||||
NBSCustomInstrument customInstrument = customInstruments.get(index);
|
|
||||||
instrument = Instrument.of(customInstrument.name);
|
|
||||||
key += customInstrument.pitch;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte layerVolume = 100;
|
|
||||||
if (nbsLayers.size() > note.layer) {
|
|
||||||
layerVolume = nbsLayers.get(note.layer).volume;
|
|
||||||
}
|
|
||||||
|
|
||||||
int pitch = key-33;
|
|
||||||
song.add(new Note(instrument, pitch, (float) note.velocity * (float) layerVolume / 10000f, getMilliTime(note.tick, tempo)));
|
|
||||||
}
|
|
||||||
|
|
||||||
song.length = song.get(song.size()-1).time + 50;
|
|
||||||
|
|
||||||
return song;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getString (ByteBuffer buffer, int maxSize) throws IOException {
|
|
||||||
int length = buffer.getInt();
|
|
||||||
if (length > maxSize) {
|
|
||||||
throw new IOException("String is too large");
|
|
||||||
}
|
|
||||||
byte arr[] = new byte[length];
|
|
||||||
buffer.get(arr, 0, length);
|
|
||||||
return new String(arr);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getMilliTime(int tick, int tempo) {
|
|
||||||
return 1000 * tick * 100 / tempo;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,32 +2,30 @@ package land.chipmunk.chipmunkmod.song;
|
||||||
|
|
||||||
|
|
||||||
public class Note implements Comparable<Note> {
|
public class Note implements Comparable<Note> {
|
||||||
public Instrument instrument;
|
public Instrument instrument;
|
||||||
public int pitch;
|
public int pitch;
|
||||||
public float volume;
|
public float volume;
|
||||||
public long time;
|
public long time;
|
||||||
|
|
||||||
public Note (Instrument instrument, int pitch, float volume, long time) {
|
public Note(Instrument instrument, int pitch, float volume, long time) {
|
||||||
this.instrument = instrument;
|
this.instrument = instrument;
|
||||||
this.pitch = pitch;
|
this.pitch = pitch;
|
||||||
this.volume = volume;
|
this.volume = volume;
|
||||||
this.time = time;
|
this.time = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(Note other) {
|
public int compareTo(Note other) {
|
||||||
if (time < other.time) {
|
if (time < other.time) {
|
||||||
return -1;
|
return -1;
|
||||||
|
} else if (time > other.time) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (time > other.time) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int noteId () {
|
public int noteId() {
|
||||||
return pitch + instrument.id * 25;
|
return pitch + instrument.id * 25;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,131 +1,132 @@
|
||||||
package land.chipmunk.chipmunkmod.song;
|
package land.chipmunk.chipmunkmod.song;
|
||||||
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
public class Song {
|
public class Song {
|
||||||
public ArrayList<Note> notes = new ArrayList<>();
|
public ArrayList<Note> notes = new ArrayList<>();
|
||||||
public Component name;
|
public Component name;
|
||||||
public int position = 0; // Current note index
|
public int position = 0; // Current note index
|
||||||
public boolean looping = false;
|
public boolean looping = false;
|
||||||
public boolean paused = true;
|
public boolean paused = true;
|
||||||
public long startTime = 0; // Start time in millis since unix epoch
|
public long startTime = 0; // Start time in millis since unix epoch
|
||||||
public long length = 0; // Milliseconds in the song
|
public long length = 0; // Milliseconds in the song
|
||||||
public long time = 0; // Time since start of song
|
public long time = 0; // Time since start of song
|
||||||
public long loopPosition = 0; // Milliseconds into the song to start looping
|
public long loopPosition = 0; // Milliseconds into the song to start looping
|
||||||
public int loopCount = 0; // Number of times to loop
|
public int loopCount = 0; // Number of times to loop
|
||||||
public int currentLoop = 0; // Number of loops so far
|
public int currentLoop = 0; // Number of loops so far
|
||||||
|
|
||||||
public Song (Component name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Song (String name) {
|
public Song(Component name) {
|
||||||
this(Component.text(name));
|
this.name = name;
|
||||||
}
|
|
||||||
|
|
||||||
public Note get (int i) {
|
|
||||||
return notes.get(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void add (Note e) {
|
|
||||||
notes.add(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sort () {
|
|
||||||
Collections.sort(notes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Starts playing song (does nothing if already playing)
|
|
||||||
*/
|
|
||||||
public void play () {
|
|
||||||
if (paused) {
|
|
||||||
paused = false;
|
|
||||||
startTime = System.currentTimeMillis() - time;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
public Song(String name) {
|
||||||
* Pauses song (does nothing if already paused)
|
this(Component.text(name));
|
||||||
*/
|
|
||||||
public void pause () {
|
|
||||||
if (!paused) {
|
|
||||||
paused = true;
|
|
||||||
// Recalculates time so that the song will continue playing after the exact point it was paused
|
|
||||||
advanceTime();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void setTime (long t) {
|
public Note get(int i) {
|
||||||
time = t;
|
return notes.get(i);
|
||||||
startTime = System.currentTimeMillis() - time;
|
|
||||||
position = 0;
|
|
||||||
while (position < notes.size() && notes.get(position).time < t) {
|
|
||||||
position++;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public void advanceTime () {
|
public void add(Note e) {
|
||||||
time = System.currentTimeMillis() - startTime;
|
notes.add(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean reachedNextNote () {
|
public void sort() {
|
||||||
if (position < notes.size()) {
|
Collections.sort(notes);
|
||||||
return notes.get(position).time <= time;
|
}
|
||||||
} else {
|
|
||||||
if (time > length && shouldLoop()) {
|
/**
|
||||||
loop();
|
* Starts playing song (does nothing if already playing)
|
||||||
if (position < notes.size()) {
|
*/
|
||||||
return notes.get(position).time <= time;
|
public void play() {
|
||||||
} else {
|
if (paused) {
|
||||||
return false;
|
paused = false;
|
||||||
|
startTime = System.currentTimeMillis() - time;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public Note getNextNote () {
|
/**
|
||||||
if (position >= notes.size()) {
|
* Pauses song (does nothing if already paused)
|
||||||
if (shouldLoop()) {
|
*/
|
||||||
loop();
|
public void pause() {
|
||||||
} else {
|
if (!paused) {
|
||||||
return null;
|
paused = true;
|
||||||
}
|
// Recalculates time so that the song will continue playing after the exact point it was paused
|
||||||
|
advanceTime();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return notes.get(position++);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean finished () {
|
public void setTime(long t) {
|
||||||
return time > length && !shouldLoop();
|
time = t;
|
||||||
}
|
startTime = System.currentTimeMillis() - time;
|
||||||
|
position = 0;
|
||||||
private void loop () {
|
while (position < notes.size() && notes.get(position).time < t) {
|
||||||
position = 0;
|
position++;
|
||||||
startTime += length - loopPosition;
|
}
|
||||||
time -= length - loopPosition;
|
|
||||||
while (position < notes.size() && notes.get(position).time < loopPosition) {
|
|
||||||
position++;
|
|
||||||
}
|
}
|
||||||
currentLoop++;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean shouldLoop () {
|
public void advanceTime() {
|
||||||
if (looping) {
|
time = System.currentTimeMillis() - startTime;
|
||||||
if (loopCount == 0) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return currentLoop < loopCount;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public int size () {
|
public boolean reachedNextNote() {
|
||||||
return notes.size();
|
if (position < notes.size()) {
|
||||||
}
|
return notes.get(position).time <= time;
|
||||||
|
} else {
|
||||||
|
if (time > length && shouldLoop()) {
|
||||||
|
loop();
|
||||||
|
if (position < notes.size()) {
|
||||||
|
return notes.get(position).time <= time;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Note getNextNote() {
|
||||||
|
if (position >= notes.size()) {
|
||||||
|
if (shouldLoop()) {
|
||||||
|
loop();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return notes.get(position++);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean finished() {
|
||||||
|
return time > length && !shouldLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loop() {
|
||||||
|
position = 0;
|
||||||
|
startTime += length - loopPosition;
|
||||||
|
time -= length - loopPosition;
|
||||||
|
while (position < notes.size() && notes.get(position).time < loopPosition) {
|
||||||
|
position++;
|
||||||
|
}
|
||||||
|
currentLoop++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldLoop() {
|
||||||
|
if (looping) {
|
||||||
|
if (loopCount == 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return currentLoop < loopCount;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return notes.size();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,20 +3,20 @@ package land.chipmunk.chipmunkmod.song;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
|
||||||
public class SongLoaderException extends Exception {
|
public class SongLoaderException extends Exception {
|
||||||
public final Text message;
|
public final Text message;
|
||||||
|
|
||||||
public SongLoaderException (Text message) {
|
public SongLoaderException(Text message) {
|
||||||
super();
|
super();
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SongLoaderException (Text message, Throwable cause) {
|
public SongLoaderException(Text message, Throwable cause) {
|
||||||
super(null, cause);
|
super(null, cause);
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getMessage () {
|
public String getMessage() {
|
||||||
return message.getString();
|
return message.getString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,58 +11,58 @@ import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
public class SongLoaderThread extends Thread {
|
public class SongLoaderThread extends Thread {
|
||||||
private String location;
|
private String location;
|
||||||
private File songPath;
|
private File songPath;
|
||||||
private URL songUrl;
|
private URL songUrl;
|
||||||
public SongLoaderException exception;
|
public SongLoaderException exception;
|
||||||
public Song song;
|
public Song song;
|
||||||
|
|
||||||
private boolean isUrl;
|
private boolean isUrl;
|
||||||
|
|
||||||
public SongLoaderThread (URL location) throws SongLoaderException {
|
public SongLoaderThread(URL location) throws SongLoaderException {
|
||||||
isUrl = true;
|
isUrl = true;
|
||||||
songUrl = location;
|
songUrl = location;
|
||||||
}
|
|
||||||
|
|
||||||
public SongLoaderThread (Path location) throws SongLoaderException {
|
|
||||||
isUrl = false;
|
|
||||||
songPath = location.toFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run () {
|
|
||||||
byte[] bytes;
|
|
||||||
String name;
|
|
||||||
try {
|
|
||||||
if (isUrl) {
|
|
||||||
bytes = DownloadUtilities.DownloadToByteArray(songUrl);
|
|
||||||
name = Paths.get(songUrl.toURI().getPath()).getFileName().toString();
|
|
||||||
} else {
|
|
||||||
bytes = Files.readAllBytes(songPath.toPath());
|
|
||||||
name = songPath.getName();
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
exception = new SongLoaderException(Text.literal(e.getMessage()), e);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
public SongLoaderThread(Path location) throws SongLoaderException {
|
||||||
song = MidiConverter.getSongFromBytes(bytes, name);
|
isUrl = false;
|
||||||
} catch (Exception e) {
|
songPath = location.toFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (song == null) {
|
public void run() {
|
||||||
try {
|
byte[] bytes;
|
||||||
song = NBSConverter.getSongFromBytes(bytes, name);
|
String name;
|
||||||
} catch (Exception e) {
|
try {
|
||||||
}
|
if (isUrl) {
|
||||||
|
bytes = DownloadUtilities.DownloadToByteArray(songUrl);
|
||||||
|
name = Paths.get(songUrl.toURI().getPath()).getFileName().toString();
|
||||||
|
} else {
|
||||||
|
bytes = Files.readAllBytes(songPath.toPath());
|
||||||
|
name = songPath.getName();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
exception = new SongLoaderException(Text.literal(e.getMessage()), e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
song = MidiConverter.getSongFromBytes(bytes, name);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
if (song == null) {
|
||||||
|
try {
|
||||||
|
song = NBSConverter.getSongFromBytes(bytes, name);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (song == null) {
|
||||||
|
exception = new SongLoaderException(Text.translatable("Invalid song format"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (song == null) {
|
private File getSongFile(String name) {
|
||||||
exception = new SongLoaderException(Text.translatable("Invalid song format"));
|
return new File(SongPlayer.SONG_DIR, name);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private File getSongFile (String name) {
|
|
||||||
return new File(SongPlayer.SONG_DIR, name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,46 +14,48 @@ import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
public class DownloadUtilities {
|
public class DownloadUtilities {
|
||||||
|
|
||||||
private static class DefaultTrustManager implements X509TrustManager {
|
private static class DefaultTrustManager implements X509TrustManager {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void checkClientTrusted(X509Certificate[] arg0, String arg1) {}
|
public void checkClientTrusted(X509Certificate[] arg0, String arg1) {
|
||||||
|
|
||||||
@Override
|
|
||||||
public void checkServerTrusted(X509Certificate[] arg0, String arg1) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public X509Certificate[] getAcceptedIssuers() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
URLConnection conn = url.openConnection();
|
|
||||||
conn.setConnectTimeout(5000);
|
|
||||||
conn.setReadTimeout(10000);
|
|
||||||
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0");
|
|
||||||
|
|
||||||
try (BufferedInputStream downloadStream = new BufferedInputStream(conn.getInputStream())) {
|
|
||||||
ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
|
|
||||||
byte[] buf = new byte[1024];
|
|
||||||
int n;
|
|
||||||
while ((n = downloadStream.read(buf)) > 0) {
|
|
||||||
byteArrayStream.write(buf, 0, n);
|
|
||||||
|
|
||||||
if (Thread.interrupted()) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return byteArrayStream.toByteArray();
|
|
||||||
}
|
|
||||||
// Closing a ByteArrayInputStream has no effect, so I do not close it.
|
|
||||||
}
|
|
||||||
|
|
||||||
public static InputStream DownloadToInputStream(URL url) throws KeyManagementException, NoSuchAlgorithmException, IOException {
|
@Override
|
||||||
return new ByteArrayInputStream(DownloadToByteArray(url));
|
public void checkServerTrusted(X509Certificate[] arg0, String arg1) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
URLConnection conn = url.openConnection();
|
||||||
|
conn.setConnectTimeout(5000);
|
||||||
|
conn.setReadTimeout(10000);
|
||||||
|
conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0");
|
||||||
|
|
||||||
|
try (BufferedInputStream downloadStream = new BufferedInputStream(conn.getInputStream())) {
|
||||||
|
ByteArrayOutputStream byteArrayStream = new ByteArrayOutputStream();
|
||||||
|
byte[] buf = new byte[1024];
|
||||||
|
int n;
|
||||||
|
while ((n = downloadStream.read(buf)) > 0) {
|
||||||
|
byteArrayStream.write(buf, 0, n);
|
||||||
|
|
||||||
|
if (Thread.interrupted()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return byteArrayStream.toByteArray();
|
||||||
|
}
|
||||||
|
// Closing a ByteArrayInputStream has no effect, so I do not close it.
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InputStream DownloadToInputStream(URL url) throws KeyManagementException, NoSuchAlgorithmException, IOException {
|
||||||
|
return new ByteArrayInputStream(DownloadToByteArray(url));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue