diff --git a/input.nbs b/input.nbs new file mode 100644 index 00000000..e69de29b diff --git a/src/main/java/com/diamondfire/helpbot/bot/HelpBotInstance.java b/src/main/java/com/diamondfire/helpbot/bot/HelpBotInstance.java index 91a593c7..fe6f3a76 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/HelpBotInstance.java +++ b/src/main/java/com/diamondfire/helpbot/bot/HelpBotInstance.java @@ -1,6 +1,5 @@ package com.diamondfire.helpbot.bot; -import com.diamondfire.helpbot.HelpBot; import com.diamondfire.helpbot.bot.command.CommandHandler; import com.diamondfire.helpbot.bot.command.impl.codeblock.*; import com.diamondfire.helpbot.bot.command.impl.other.*; @@ -109,7 +108,9 @@ public static void initialize() throws LoginException { new ExcuseStaffCommand(), new ExcusedStaffCommand(), new SupportBannedPlayersCommand(), - new DiscussionMuteCommand() + new DiscussionMuteCommand(), + new NbsCommand(), + new DailySessionsCommand() ); JDABuilder builder = JDABuilder.createDefault(config.getToken()) @@ -140,4 +141,4 @@ public static Config getConfig() { public static TaskRegistry getScheduler() { return loop; } -} +} \ No newline at end of file diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/argument/impl/types/AbstractOffsetArgument.java b/src/main/java/com/diamondfire/helpbot/bot/command/argument/impl/types/AbstractOffsetArgument.java index 149171f5..ebbe6db7 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/argument/impl/types/AbstractOffsetArgument.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/argument/impl/types/AbstractOffsetArgument.java @@ -7,6 +7,16 @@ public abstract class AbstractOffsetArgument extends AbstractSimpleValueArgument { + private final boolean reverse; + + public AbstractOffsetArgument() { + this(false); + } + + public AbstractOffsetArgument(boolean reverse) { + this.reverse = reverse; + } + @Override protected Date parse(@NotNull String argument) throws ArgumentException { Calendar calendar = Calendar.getInstance(); @@ -23,8 +33,17 @@ protected Date parse(@NotNull String argument) throws ArgumentException { if (!Character.isDigit(currentChar)) { if (durationMap.containsKey(currentChar)) { - calendar.add(durationMap.get(currentChar), Integer.parseInt(argument.substring(offset, i))); - modified = true; + try { + int key = Integer.parseInt(argument.substring(offset, i)); + if (reverse) { + key *= -1; + } + + calendar.add(durationMap.get(currentChar), key); + modified = true; + } catch (NumberFormatException e) { + throw new MalformedArgumentException("Malformed duration! Provided token " + currentChar + " had an invalid duration."); + } } else { List units = new ArrayList<>(); for (Character character : durationMap.keySet()) { @@ -38,7 +57,12 @@ protected Date parse(@NotNull String argument) throws ArgumentException { } if (!modified) { - throw new MalformedArgumentException("Malformed duration!"); + List units = new ArrayList<>(); + for (Character character : durationMap.keySet()) { + units.add(character.toString()); + } + + throw new MalformedArgumentException("Malformed duration!" + " \nPossible time units are: " + String.join(",", units)); } return calendar.getTime(); diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/argument/impl/types/DateOffsetArgument.java b/src/main/java/com/diamondfire/helpbot/bot/command/argument/impl/types/DateOffsetArgument.java index 9426cb4b..658a2350 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/argument/impl/types/DateOffsetArgument.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/argument/impl/types/DateOffsetArgument.java @@ -4,12 +4,17 @@ public class DateOffsetArgument extends AbstractOffsetArgument { + public DateOffsetArgument() { + super(); + } + @Override protected Duration[] getDurations() { return new Duration[]{ new Duration(Calendar.DAY_OF_MONTH, 'd'), new Duration(Calendar.DAY_OF_WEEK, 'w'), new Duration(Calendar.MONTH, 'm'), + new Duration(Calendar.YEAR, 'y'), }; } diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/argument/impl/types/TimeOffsetArgument.java b/src/main/java/com/diamondfire/helpbot/bot/command/argument/impl/types/TimeOffsetArgument.java index 86e37f84..65e11ed2 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/argument/impl/types/TimeOffsetArgument.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/argument/impl/types/TimeOffsetArgument.java @@ -4,6 +4,14 @@ public class TimeOffsetArgument extends AbstractOffsetArgument { + public TimeOffsetArgument() { + super(); + } + + public TimeOffsetArgument(boolean reverse) { + super(reverse); + } + @Override protected Duration[] getDurations() { return new Duration[]{ diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/other/NbsCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/other/NbsCommand.java new file mode 100644 index 00000000..ecf23771 --- /dev/null +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/other/NbsCommand.java @@ -0,0 +1,121 @@ +package com.diamondfire.helpbot.bot.command.impl.other; + +import com.diamondfire.helpbot.bot.command.argument.ArgumentSet; +import com.diamondfire.helpbot.bot.command.help.CommandCategory; +import com.diamondfire.helpbot.bot.command.help.HelpContext; +import com.diamondfire.helpbot.bot.command.impl.Command; +import com.diamondfire.helpbot.bot.command.permissions.Permission; +import com.diamondfire.helpbot.bot.command.reply.PresetBuilder; +import com.diamondfire.helpbot.bot.command.reply.feature.informative.InformativeReply; +import com.diamondfire.helpbot.bot.command.reply.feature.informative.InformativeReplyType; +import com.diamondfire.helpbot.bot.events.CommandEvent; +import com.diamondfire.helpbot.util.nbs.*; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import net.dv8tion.jda.api.EmbedBuilder; +import net.dv8tion.jda.api.entities.Message; +import net.dv8tion.jda.api.entities.TextChannel; + +import java.awt.*; +import java.io.*; +import java.net.*; +import java.nio.charset.StandardCharsets; + +import java.util.Scanner; +import java.util.concurrent.CompletableFuture; + +public class NbsCommand extends Command { + + @Override + public String getName() { + return "nbs"; + } + + @Override + public HelpContext getHelpContext() { + return new HelpContext() + .description("Generates a Codeutils song function.") + .category(CommandCategory.OTHER); + } + + @Override + protected ArgumentSet compileArguments() { return new ArgumentSet(); } + + @Override + public Permission getPermission() { return Permission.USER; } + + @Override + public void run(CommandEvent event) { + TextChannel channel = event.getChannel(); + PresetBuilder preset = new PresetBuilder(); + preset.withPreset(new InformativeReply(InformativeReplyType.ERROR,"You need to attach an nbs file!")); + if(event.getMessage().getAttachments().isEmpty()) { + event.reply(preset); + return; + } + Message.Attachment attachment = event.getMessage().getAttachments().get(0); + if(!attachment.getFileExtension().equals("nbs")) { + event.reply(preset); + return; + } + EmbedBuilder errorEmbed = new EmbedBuilder() + .setColor(Color.RED) + .setTitle("An error occurred!"); + try { + File file = new File("input.nbs"); + System.out.println(event.getMessage().getAttachments().get(0).getFileExtension()); + CompletableFuture.runAsync(() -> { + CompletableFuture task = attachment.downloadToFile(file); + while(!task.isDone()) { } + try { + String code = new NBSToTemplate(NBSDecoder.parse(file)).convert(); + byte[] b64 = CompressionUtil.toBase64(CompressionUtil.toGZIP(code.getBytes(StandardCharsets.UTF_8))); + String jsonInputString = String.format("{\"template\": \"%s\",\"temp\": true}",new String(b64)); + JsonObject json = new Gson().fromJson(generateLink(jsonInputString),JsonObject.class); + + EmbedBuilder embed = new EmbedBuilder() + .setColor(new Color(70,199,82)) + .setTitle("Function Generated!") + .setThumbnail("https://static.wikia.nocookie.net/minecraft/images/9/9b/Note_Block.png/revision/latest?cb=20190921170620") + .addField("Link: __Expires in 2 mins__","[Function Link](https://derpystuff.gitlab.io/code/l?link=" + json.get("link").getAsString() + ")",false) + .addField("Info:","Click the link shown above and click the button in the bottom left corner to copy the give command for the template. You will need [this function](https://derpystuff.gitlab.io/code/l?link=7cf5d91c35bbde31c28567d8d8945c40) to play songs.",false); + + channel.sendMessage(embed.build()).queue(); + } catch(OutdatedNBSException e) { + e.printStackTrace(); + channel.sendMessage(errorEmbed.build()).queue(); + } catch(IOException e) { + e.printStackTrace(); + channel.sendMessage(errorEmbed.build()).queue(); + } + }); + } catch(Exception e) { + e.printStackTrace(); + channel.sendMessage(errorEmbed.build()).queue(); + } + + } + private static String generateLink(String templateData) throws IOException { + URL url = new URL("https://twv.vercel.app/v2/create"); + URLConnection con = url.openConnection(); + HttpURLConnection http = (HttpURLConnection) con; + http.setRequestMethod("POST"); + http.setDoOutput(true); + byte[] out = templateData.getBytes(StandardCharsets.UTF_8); + int length = out.length; + + http.setFixedLengthStreamingMode(length); + http.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); + http.setRequestProperty("Accept","application/json; charset=UTF-8"); + http.connect(); + try(OutputStream os = http.getOutputStream()) { + os.write(out); + } + Scanner s = new Scanner(http.getInputStream()).useDelimiter("\\A"); + String result = s.hasNext() ? s.next() : ""; + s.close(); + http.disconnect(); + + return result; + } +} diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/other/PollCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/other/PollCommand.java index abbc546a..7a9cef95 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/other/PollCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/other/PollCommand.java @@ -1,9 +1,12 @@ package com.diamondfire.helpbot.bot.command.impl.other; import com.diamondfire.helpbot.bot.command.argument.ArgumentSet; +import com.diamondfire.helpbot.bot.command.argument.impl.parsing.types.MessageArgument; import com.diamondfire.helpbot.bot.command.help.*; import com.diamondfire.helpbot.bot.command.impl.Command; import com.diamondfire.helpbot.bot.command.permissions.Permission; +import com.diamondfire.helpbot.bot.command.reply.PresetBuilder; +import com.diamondfire.helpbot.bot.command.reply.feature.informative.*; import com.diamondfire.helpbot.bot.events.CommandEvent; import com.diamondfire.helpbot.util.Util; import net.dv8tion.jda.api.EmbedBuilder; @@ -14,49 +17,58 @@ import static com.diamondfire.helpbot.bot.HelpBotInstance.getConfig; public class PollCommand extends Command { - - + + @Override public String getName() { return "poll"; } - + @Override public HelpContext getHelpContext() { return new HelpContext() .description("Creates a poll.") - .category(CommandCategory.OTHER); + .category(CommandCategory.OTHER). + addArgument(new HelpContextArgument() + .name("text|input")); } - + @Override public ArgumentSet compileArguments() { - return new ArgumentSet(); + return new ArgumentSet(). + addArgument("input", + new MessageArgument()); } - + @Override public Permission getPermission() { return Permission.DEVELOPER; } - + @Override public void run(CommandEvent event) { - + String input = event.getArgument("input"); //sends arguments on a ?poll command - if (event.getMessage().getContentRaw().equals(getConfig().getPrefix() + "poll")) { - - EmbedBuilder error = new EmbedBuilder(); - error.setTitle("Poll Command"); - error.setDescription("The arguments for the poll command are:\n" + getConfig().getPrefix() + "poll [Question]\\|[Option 1]\\|[Option 2]\\|"); - error.setColor(Color.RED); - - event.getChannel().sendMessage(error.build()).queue(); - + if (input.isEmpty()) { + PresetBuilder preset = new PresetBuilder(); + preset.withPreset(new InformativeReply(InformativeReplyType.ERROR, "Poll Command", "The arguments for the poll command are:\n" + getConfig().getPrefix() + "poll [Question]\\|[Option 1]\\|[Option 2]\\|")); + event.reply(preset); return; } ArrayList pollOptions = new ArrayList<>(); - pollOptions.addAll(Arrays.asList(event.getMessage().getContentRaw().split("\\|"))); //poll options + poll question (contains ?poll) - String pollQuestion = String.valueOf(pollOptions.get(0).subSequence(6,pollOptions.get(0).length())); //poll question (does not contain ?poll) + pollOptions.addAll(Arrays.asList(input.split("\\|"))); //poll options + poll question + + //checks if there are no arguments + if (pollOptions.isEmpty()) { + PresetBuilder preset = new PresetBuilder(); + preset.withPreset(new InformativeReply(InformativeReplyType.ERROR, "The arguments are incorrect. Correct arguments are:\\n" + getConfig().getPrefix() + "poll [Question]\\\\|[Option 1]\\\\|[Option 2]\\\\|")); + event.reply(preset); + return; + } + + + String pollQuestion = pollOptions.get(0); //poll question pollOptions.remove(0); //remove the poll question so only the options remain ArrayList fullPollOptions = new ArrayList<>(); @@ -81,39 +93,24 @@ public void run(CommandEvent event) { i += 2; } - + EmbedBuilder builder = new EmbedBuilder(); builder.setTitle(pollQuestion); //sets title to poll question builder.setDescription(String.join(" ", fullPollOptions)); //adds poll options builder.setColor(new Color(33, 40, 97)); - - int len = pollOptions.toArray().length; //get amount of poll options - - //checks if there are no arguments - if (len == 0) { - - EmbedBuilder error = new EmbedBuilder(); - error.setTitle("Error!"); - error.setDescription("The arguments are incorrect. Correct arguments are:\n" + getConfig().getPrefix() + "poll [Question]\\|[Option 1]\\|[Option 2]\\|"); - error.setColor(Color.RED); - - event.getChannel().sendMessage(error.build()).queue(); - - return; - } event.getChannel().sendMessage(builder.build()).queue((message) -> { //send embed message - + //add reactions Deque nums = Util.getUnicodeNumbers(); for (String option : pollOptions) { message.addReaction(nums.pop()).queue(); } - + }); //delete original message event.getMessage().delete().queue(); - + } } diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/other/VerifyCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/other/VerifyCommand.java index 619b6cf5..032166ad 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/other/VerifyCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/other/VerifyCommand.java @@ -10,8 +10,8 @@ import com.diamondfire.helpbot.bot.events.CommandEvent; import com.diamondfire.helpbot.sys.database.impl.DatabaseQuery; import com.diamondfire.helpbot.sys.database.impl.queries.BasicQuery; -import com.diamondfire.helpbot.util.*; -import net.dv8tion.jda.api.entities.*; +import com.diamondfire.helpbot.util.Util; +import net.dv8tion.jda.api.entities.Guild; import java.sql.ResultSet; @@ -58,7 +58,7 @@ public void run(CommandEvent event) { String minecraftPlayer = event.getArgument("mcname"); new DatabaseQuery() - .query(new BasicQuery("SELECT * FROM hypercube.players WHERE players.name = ? OR players.uuid = ? LIMIT 1;", (statement) -> { + .query(new BasicQuery("SELECT * FROM players WHERE players.name = ? OR players.uuid = ? LIMIT 1;", (statement) -> { statement.setString(1, minecraftPlayer); statement.setString(2, minecraftPlayer); })) @@ -82,15 +82,18 @@ public void run(CommandEvent event) { ); Guild guild = event.getGuild(); guild.addRoleToMember(member, guild.getRoleById((VerifyCommand.ROLE_ID))).queue(); + + // Run the query before any messages sent to make sure that they are actually added. + new DatabaseQuery() + .query(new BasicQuery("INSERT INTO linked_accounts (player_uuid, player_name, discord_id) VALUES (?,?,?) ON DUPLICATE KEY UPDATE discord_id = ?", (statement) -> { + statement.setString(1, uuid); + statement.setString(2, name); + statement.setString(3, userString); + statement.setString(4, userString); + })).compile(); + event.reply(builder); - new DatabaseQuery() - .query(new BasicQuery("INSERT INTO hypercube.linked_accounts (player_uuid, player_name, discord_id) VALUES (?,?,?) ON DUPLICATE KEY UPDATE discord_id = ?", (statement) -> { - statement.setString(1, uuid); - statement.setString(2, name); - statement.setString(3, userString); - statement.setString(4, userString); - })).compile(); Util.updateMember(member); PresetBuilder log = new PresetBuilder() diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/QueueCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/QueueCommand.java index d3647264..7bf64c57 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/QueueCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/QueueCommand.java @@ -49,7 +49,7 @@ public void run(CommandEvent event) { EmbedBuilder embed = preset.getEmbed(); new DatabaseQuery() - .query(new BasicQuery("SELECT player, plot, node, staff, TIMEDIFF(CURRENT_TIMESTAMP(), enter_time) AS time FROM hypercube.support_queue ORDER BY enter_time LIMIT 25;")) + .query(new BasicQuery("SELECT player, plot, node, staff, TIMEDIFF(CURRENT_TIMESTAMP(), enter_time) AS time FROM support_queue ORDER BY enter_time LIMIT 25;")) .compile() .run((result) -> { if (result.isEmpty()) { diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/StaffListCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/StaffListCommand.java index 498c618f..04d58d84 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/StaffListCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/StaffListCommand.java @@ -51,7 +51,7 @@ public void run(CommandEvent event) { builder.setChannel(event.getChannel().getIdLong()); builder.setUser(event.getMember().getIdLong()); new DatabaseQuery() - .query(new BasicQuery("SELECT * FROM hypercube.ranks,hypercube.players\n" + + .query(new BasicQuery("SELECT * FROM ranks,players\n" + " WHERE ranks.uuid = players.uuid\n" + " AND (ranks.support > 0 || ranks.moderation > 0 || ranks.administration > 0 || ranks.builder = 1) AND ranks.retirement = 0")) .compile() diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/graph/AbstractGraphCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/graph/AbstractGraphCommand.java index f3316c57..ca7aea34 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/graph/AbstractGraphCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/graph/AbstractGraphCommand.java @@ -6,8 +6,9 @@ import com.diamondfire.helpbot.bot.command.permissions.Permission; import com.diamondfire.helpbot.bot.events.CommandEvent; import com.diamondfire.helpbot.sys.graph.generators.*; +import com.diamondfire.helpbot.sys.graph.generators.context.TimeGraphContext; -public abstract class AbstractGraphCommand extends Command { +public abstract class AbstractGraphCommand extends Command { @Override public ArgumentSet compileArguments() { @@ -25,13 +26,14 @@ public Permission getPermission() { @Override public void run(CommandEvent event) { - TimeMode mode = event.getArgument("mode"); - int amount = event.getArgument("amount"); + T context = createContext(event); - event.getChannel().sendFile(getGraphGenerator().createGraph(mode, amount)).queue(); + event.getChannel().sendFile(getGraphGenerator().createGraph(context)).queue(); } - public abstract GraphGenerator getGraphGenerator(); + public abstract GraphGenerator getGraphGenerator(); + + public abstract T createContext(CommandEvent event); } diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/graph/NewJoinGraphCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/graph/NewJoinGraphCommand.java index 8cd4905d..9339b4ab 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/graph/NewJoinGraphCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/graph/NewJoinGraphCommand.java @@ -1,9 +1,11 @@ package com.diamondfire.helpbot.bot.command.impl.stats.graph; import com.diamondfire.helpbot.bot.command.help.*; +import com.diamondfire.helpbot.bot.events.CommandEvent; import com.diamondfire.helpbot.sys.graph.generators.*; +import com.diamondfire.helpbot.sys.graph.generators.context.TimeGraphContext; -public class NewJoinGraphCommand extends AbstractGraphCommand { +public class NewJoinGraphCommand extends AbstractGraphCommand { @Override public String getName() { @@ -24,9 +26,17 @@ public HelpContext getHelpContext() { } @Override - public GraphGenerator getGraphGenerator() { + public GraphGenerator getGraphGenerator() { return GraphGenerators.NEW_PLAYERS; } + + @Override + public TimeGraphContext createContext(CommandEvent event) { + TimeMode mode = event.getArgument("mode"); + int amount = event.getArgument("amount"); + + return new TimeGraphContext(mode, amount); + } } diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/graph/PlayerJoinGraphCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/graph/PlayerJoinGraphCommand.java index d3f90564..3f594564 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/graph/PlayerJoinGraphCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/graph/PlayerJoinGraphCommand.java @@ -1,9 +1,11 @@ package com.diamondfire.helpbot.bot.command.impl.stats.graph; import com.diamondfire.helpbot.bot.command.help.*; +import com.diamondfire.helpbot.bot.events.CommandEvent; import com.diamondfire.helpbot.sys.graph.generators.*; +import com.diamondfire.helpbot.sys.graph.generators.context.TimeGraphContext; -public class PlayerJoinGraphCommand extends AbstractGraphCommand { +public class PlayerJoinGraphCommand extends AbstractGraphCommand { @Override public String getName() { @@ -24,9 +26,17 @@ public HelpContext getHelpContext() { } @Override - public GraphGenerator getGraphGenerator() { + public GraphGenerator getGraphGenerator() { return GraphGenerators.UNIQUE_JOINS; } + + @Override + public TimeGraphContext createContext(CommandEvent event) { + TimeMode mode = event.getArgument("mode"); + int amount = event.getArgument("amount"); + + return new TimeGraphContext(mode, amount); + } } diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/individualized/LastJoinedCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/individualized/LastJoinedCommand.java index d05624a7..a7aa9605 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/individualized/LastJoinedCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/individualized/LastJoinedCommand.java @@ -67,7 +67,7 @@ protected void execute(CommandEvent event, String player) { new MinecraftUserPreset(formattedName) ); new DatabaseQuery() - .query(new BasicQuery("SELECT time AS time FROM hypercube.player_join_log WHERE uuid = ? ORDER BY time DESC LIMIT 1;", (statement) -> statement.setString(1, set.getString("uuid")))) + .query(new BasicQuery("SELECT time AS time FROM player_join_log WHERE uuid = ? ORDER BY time DESC LIMIT 1;", (statement) -> statement.setString(1, set.getString("uuid")))) .compile() .run((resultTableDate) -> { if (resultTableDate.isEmpty()) { diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/individualized/ProfileCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/individualized/ProfileCommand.java index 8a2d8731..56748f8f 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/individualized/ProfileCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/individualized/ProfileCommand.java @@ -56,8 +56,8 @@ protected void execute(CommandEvent event, String player) { new DatabaseQuery() .query(new BasicQuery("SELECT * " + - "FROM hypercube.ranks," + - " hypercube.players " + + "FROM ranks," + + " players " + "WHERE ranks.uuid = players.uuid" + " AND (players.uuid = ? || players.name = ?)", (statement) -> { statement.setString(1, player); @@ -100,9 +100,9 @@ protected void execute(CommandEvent event, String player) { new DatabaseQuery() .query(new BasicQuery("SELECT * FROM (SELECT (SELECT date AS liteban_join FROM litebans.history WHERE uuid = ? ORDER BY date DESC LIMIT 1) temp FROM dual) AS liteban," + " (SELECT (SELECT date AS owen_join FROM owen.join_log WHERE uuid = ? ORDER BY date DESC LIMIT 1) temp FROM dual) AS owen_join," + - " (SELECT (SELECT COUNT(*) AS votes FROM hypercube.plot_votes WHERE uuid = ?) temp FROM dual) AS votes," + - " (SELECT (SELECT tokens FROM hypercube.user_tokens WHERE uuid = ?) temp FROM dual) AS credits," + - " (SELECT (SELECT discord_id FROM hypercube.linked_accounts WHERE player_uuid = ?) temp FROM dual) AS id", (statement) -> { + " (SELECT (SELECT COUNT(*) AS votes FROM plot_votes WHERE uuid = ?) temp FROM dual) AS votes," + + " (SELECT (SELECT tokens FROM user_tokens WHERE uuid = ?) temp FROM dual) AS credits," + + " (SELECT (SELECT discord_id FROM linked_accounts WHERE player_uuid = ?) temp FROM dual) AS id", (statement) -> { statement.setString(1, playerUUID); statement.setString(2, playerUUID); statement.setString(3, playerUUID); diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/plot/PlotCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/plot/PlotCommand.java index 66d2c651..d9bbe6c9 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/plot/PlotCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/plot/PlotCommand.java @@ -43,7 +43,7 @@ public Permission getPermission() { public ResultSet getPlot(CommandEvent event) { try { Connection connection = ConnectionProvider.getConnection(); - PreparedStatement statement = connection.prepareStatement("SELECT * FROM hypercube.plots WHERE id = ?"); + PreparedStatement statement = connection.prepareStatement("SELECT * FROM plots WHERE id = ?"); statement.setInt(1, event.getArgument("id")); return statement.executeQuery(); diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/plot/PlotLocCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/plot/PlotLocCommand.java index 49cba0b9..ee94dcf8 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/plot/PlotLocCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/plot/PlotLocCommand.java @@ -41,7 +41,7 @@ public ArgumentSet compileArguments() { .addArgument("z", new IntegerArgument()) .addArgument("node", - new SingleArgumentContainer<>(new DefinedObjectArgument<>(1, 2, 3, 4)).optional(null)); + new SingleArgumentContainer<>(new DefinedObjectArgument<>(1, 2, 3, 4, 5)).optional(null)); } @Override @@ -57,7 +57,7 @@ public ResultSet getPlot(CommandEvent event) { boolean nodeSpecific = event.getArgument("node") != null; PreparedStatement statement; if (nodeSpecific) { - statement = connection.prepareStatement("SELECT * FROM hypercube.plots WHERE ? BETWEEN xmin AND xmin + (CASE" + + statement = connection.prepareStatement("SELECT * FROM plots WHERE ? BETWEEN xmin AND xmin + (CASE" + " WHEN plotsize = 1 THEN 51" + " WHEN plotsize = 2 THEN 101" + " WHEN plotsize = 3 THEN 301" + @@ -68,7 +68,7 @@ public ResultSet getPlot(CommandEvent event) { statement.setObject(3, event.getArgument("node")); } else { - statement = connection.prepareStatement("SELECT * FROM hypercube.plots WHERE ? BETWEEN xmin AND xmin + (CASE" + + statement = connection.prepareStatement("SELECT * FROM plots WHERE ? BETWEEN xmin AND xmin + (CASE" + " WHEN plotsize = 1 THEN 51" + " WHEN plotsize = 2 THEN 101" + " WHEN plotsize = 3 THEN 301" + diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/DailySessionsCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/DailySessionsCommand.java new file mode 100644 index 00000000..39b70d1f --- /dev/null +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/DailySessionsCommand.java @@ -0,0 +1,99 @@ +package com.diamondfire.helpbot.bot.command.impl.stats.support; + +import com.diamondfire.helpbot.bot.command.argument.ArgumentSet; +import com.diamondfire.helpbot.bot.command.argument.impl.parsing.types.SingleArgumentContainer; +import com.diamondfire.helpbot.bot.command.argument.impl.types.DateArgument; +import com.diamondfire.helpbot.bot.command.help.*; +import com.diamondfire.helpbot.bot.command.impl.Command; +import com.diamondfire.helpbot.bot.command.permissions.Permission; +import com.diamondfire.helpbot.bot.events.CommandEvent; +import com.diamondfire.helpbot.sys.database.impl.DatabaseQuery; +import com.diamondfire.helpbot.sys.database.impl.queries.BasicQuery; +import com.diamondfire.helpbot.sys.graph.graphable.*; +import com.diamondfire.helpbot.sys.graph.impl.ChartGraphBuilder; +import com.diamondfire.helpbot.util.DateUtil; + +import java.sql.ResultSet; +import java.time.Instant; +import java.util.*; + + +public class DailySessionsCommand extends Command { + + @Override + public String getName() { + return "dailysessions"; + } + + @Override + public String[] getAliases() { + return new String[]{"ds"}; + } + + @Override + public HelpContext getHelpContext() { + return new HelpContext() + .description("Generates a graph of all sessions done in a specific day.") + .category(CommandCategory.SUPPORT) + .addArgument( + new HelpContextArgument() + .name("date") + .optional() + ); + } + + @Override + public ArgumentSet compileArguments() { + return new ArgumentSet() + .addArgument("date", + new SingleArgumentContainer<>(new DateArgument()).optional(null)); + + } + + @Override + public Permission getPermission() { + return Permission.SUPPORT; + } + + @Override + public void run(CommandEvent event) { + Date date; + if (event.getArgument("date") == null) { + date = Date.from(Instant.now()); + } else { + date = event.getArgument("date"); + } + + java.sql.Date sqlDate = DateUtil.toSqlDate(date); + + new DatabaseQuery() + .query(new BasicQuery("SELECT hour(time) AS time, COUNT(*) AS count\n" + + "FROM support_sessions\n" + + "WHERE DATE(time) = ?\n" + + "GROUP BY hour(time)\n" + + "ORDER BY time", + (statement) -> statement.setDate(1, sqlDate)) + ) + .compile() + .run((query) -> { + Map, Integer> dates = new LinkedHashMap<>(); + ResultSet set = query.getResult(); + + for (int i = 0; i < 25; i++) { + boolean end = set.next(); + String timedisplay = i + ""; + if (i < 10) { + timedisplay = "0" + timedisplay; + } + dates.put(new StringEntry(timedisplay + ":00"), !end ? 0 : set.getInt("count")); + } + + event.getChannel().sendFile(new ChartGraphBuilder() + .setGraphName(String.format("Total sessions on %s", date)) + .createGraph(dates)).queue(); + + }); + + } + +} \ No newline at end of file diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/ExcuseStaffCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/ExcuseStaffCommand.java index 34a5ab6f..59b30d36 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/ExcuseStaffCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/ExcuseStaffCommand.java @@ -70,7 +70,7 @@ public void run(CommandEvent event) { PresetBuilder builder = new PresetBuilder(); new DatabaseQuery() - .query(new BasicQuery("SELECT * FROM hypercube.players WHERE name = ? OR uuid = ?", + .query(new BasicQuery("SELECT * FROM players WHERE name = ? OR uuid = ?", (statement) -> { statement.setString(1, username); statement.setString(2, username); diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/ExcusedStaffCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/ExcusedStaffCommand.java index 7a83fa14..3ff89fc4 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/ExcusedStaffCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/ExcusedStaffCommand.java @@ -60,8 +60,8 @@ public void run(CommandEvent event) { " excused_till," + " reason " + "FROM owen.excused_staff " + - "LEFT JOIN hypercube.ranks r ON excused_staff.uuid = r.uuid " + - "LEFT JOIN hypercube.players p ON excused_staff.uuid = p.uuid " + + "LEFT JOIN ranks r ON excused_staff.uuid = r.uuid " + + "LEFT JOIN players p ON excused_staff.uuid = p.uuid " + "WHERE (support > 0 || moderation > 0) AND (excused_till > CURRENT_TIMESTAMP() || !handled) " + "ORDER BY excused_till DESC;")) .compile() diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/FindSupporteeNamesCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/FindSupporteeNamesCommand.java index 4a269d83..64302441 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/FindSupporteeNamesCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/FindSupporteeNamesCommand.java @@ -83,7 +83,7 @@ protected void execute(CommandEvent event, String player) { for (NameDateRange range : nameRanges) { if (range.getAfter() == null) { new DatabaseQuery() - .query(new BasicQuery("SELECT * FROM hypercube.support_sessions WHERE name = ? AND time > ? LIMIT 1", (statement) -> { + .query(new BasicQuery("SELECT * FROM support_sessions WHERE name = ? AND time > ? LIMIT 1", (statement) -> { statement.setString(1, range.getName()); statement.setDate(2, DateUtil.toSqlDate(range.getBefore())); })) @@ -95,7 +95,7 @@ protected void execute(CommandEvent event, String player) { }); } else if (range.getBefore() == null) { new DatabaseQuery() - .query(new BasicQuery("SELECT * FROM hypercube.support_sessions WHERE name = ? AND time < ? LIMIT 1", (statement) -> { + .query(new BasicQuery("SELECT * FROM support_sessions WHERE name = ? AND time < ? LIMIT 1", (statement) -> { statement.setString(1, range.getName()); statement.setDate(2, DateUtil.toSqlDate(range.getAfter())); })) @@ -107,7 +107,7 @@ protected void execute(CommandEvent event, String player) { }); } else { new DatabaseQuery() - .query(new BasicQuery("SELECT * FROM hypercube.support_sessions WHERE name = ? AND time BETWEEN ? AND ? LIMIT 1", (statement) -> { + .query(new BasicQuery("SELECT * FROM support_sessions WHERE name = ? AND time BETWEEN ? AND ? LIMIT 1", (statement) -> { statement.setString(1, range.getName()); statement.setDate(2, DateUtil.toSqlDate(range.getBefore())); statement.setDate(3, DateUtil.toSqlDate(range.getAfter())); diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/JoinBadCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/JoinBadCommand.java index f04f38fe..f020e4fb 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/JoinBadCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/JoinBadCommand.java @@ -65,13 +65,13 @@ public void run(CommandEvent event) { new DatabaseQuery() .query(new BasicQuery("SELECT DISTINCT p.name, DATEDIFF(CURRENT_TIMESTAMP(), latest) AS day " + "FROM (SELECT players.uuid, name" + - " FROM hypercube.ranks," + - " hypercube.players" + + " FROM ranks," + + " players" + " WHERE ranks.uuid = players.uuid" + " AND players.uuid NOT IN (SELECT DISTINCT uuid FROM owen.excused_staff WHERE excused_till > CURRENT_TIMESTAMP())" + " AND ranks.administration = 0" + " AND ranks.support > 0 | ranks.moderation > 0) p" + - " LEFT JOIN (SELECT uuid, MAX(time) AS latest FROM hypercube.player_join_log GROUP BY uuid) cn" + + " LEFT JOIN (SELECT uuid, MAX(time) AS latest FROM player_join_log GROUP BY uuid) cn" + " ON cn.uuid = p.uuid " + "WHERE DATEDIFF(CURRENT_TIMESTAMP(), latest) >= ? " + "ORDER BY day DESC;", (statement) -> statement.setInt(1, num))) diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/SessionsCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/SessionsCommand.java index a2416f80..b5781ca4 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/SessionsCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/SessionsCommand.java @@ -30,7 +30,7 @@ public HelpContext getHelpContext() { protected List getSessions(String player) { List sessions = new ArrayList<>(); new DatabaseQuery() - .query(new BasicQuery("SELECT * FROM hypercube.support_sessions WHERE staff = ? ORDER BY time", (statement) -> statement.setString(1, player))) + .query(new BasicQuery("SELECT * FROM support_sessions WHERE staff = ? ORDER BY time", (statement) -> statement.setString(1, player))) .compile() .run((result) -> { for (ResultSet set : result) { diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/StatsCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/StatsCommand.java index fe9e6651..470dffcf 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/StatsCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/StatsCommand.java @@ -1,5 +1,8 @@ package com.diamondfire.helpbot.bot.command.impl.stats.support; +import com.diamondfire.helpbot.bot.command.argument.ArgumentSet; +import com.diamondfire.helpbot.bot.command.argument.impl.parsing.types.SingleArgumentContainer; +import com.diamondfire.helpbot.bot.command.argument.impl.types.TimeOffsetArgument; import com.diamondfire.helpbot.bot.command.help.*; import com.diamondfire.helpbot.bot.command.impl.stats.AbstractPlayerUUIDCommand; import com.diamondfire.helpbot.bot.command.permissions.Permission; @@ -9,7 +12,7 @@ import com.diamondfire.helpbot.bot.events.CommandEvent; import com.diamondfire.helpbot.sys.database.impl.DatabaseQuery; import com.diamondfire.helpbot.sys.database.impl.queries.BasicQuery; -import com.diamondfire.helpbot.util.FormatUtil; +import com.diamondfire.helpbot.util.*; import net.dv8tion.jda.api.EmbedBuilder; import java.sql.*; @@ -30,10 +33,20 @@ public HelpContext getHelpContext() { .addArgument( new HelpContextArgument() .name("player") + .optional(), + new HelpContextArgument() + .name("timeframe") .optional() ); } + @Override + public ArgumentSet compileArguments() { + return super.compileArguments() + .addArgument("timeframe", + new SingleArgumentContainer<>(new TimeOffsetArgument(true)).optional(null)); + } + @Override public Permission getPermission() { return Permission.RETIRED_SUPPORT; @@ -52,7 +65,19 @@ protected void execute(CommandEvent event, String player) { "SUM(duration) AS total_duration," + "MIN(time) AS earliest_time," + "MAX(time) AS latest_time," + - "COUNT(DISTINCT name) AS unique_helped, staff FROM support_sessions WHERE staff = ?;", (statement) -> statement.setString(1, player))) + "COUNT(DISTINCT name) AS unique_helped, staff FROM support_sessions WHERE staff = ? AND (time > ? OR ?);", + (statement) -> { + statement.setString(1, player); + + java.util.Date date = event.getArgument("timeframe"); + Timestamp sqlTimestamp = null; + if (date != null) { + sqlTimestamp = DateUtil.toTimeStamp(date); + } + + statement.setTimestamp(2, sqlTimestamp); + statement.setBoolean(3, date == null); + })) .compile() .run((result) -> { ResultSet set = result.getResult(); @@ -69,7 +94,7 @@ protected void execute(CommandEvent event, String player) { new DatabaseQuery() .query(new BasicQuery("SELECT COUNT(*) AS count, SUM(duration) AS total_time, " + - "? IN (SELECT players.name FROM hypercube.ranks, hypercube.players WHERE ranks.uuid = players.uuid AND ranks.support >= 1 AND ranks.moderation = 0 AND ranks.administration = 0) AS support," + + "? IN (SELECT players.name FROM ranks, players WHERE ranks.uuid = players.uuid AND ranks.support >= 1 AND ranks.moderation = 0 AND ranks.administration = 0) AS support," + "(COUNT(*) < 5) AS bad FROM support_sessions WHERE staff = ? AND time > CURRENT_TIMESTAMP() - INTERVAL 30 DAY;", (statement) -> { statement.setString(1, player); statement.setString(2, player); @@ -124,4 +149,4 @@ protected void execute(CommandEvent event, String player) { event.reply(preset); } -} +} \ No newline at end of file diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/StatsGraphCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/StatsGraphCommand.java index 5aadba0c..3296b356 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/StatsGraphCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/StatsGraphCommand.java @@ -46,11 +46,11 @@ public Permission getPermission() { protected void execute(CommandEvent event, String player) { new DatabaseQuery() .query(new BasicQuery("WITH RECURSIVE all_dates(dt) AS (\n" + - " SELECT (SELECT DATE(time) FROM hypercube.support_sessions WHERE staff = ? ORDER BY time LIMIT 1) dt\n" + + " SELECT (SELECT DATE(time) FROM support_sessions WHERE staff = ? ORDER BY time LIMIT 1) dt\n" + " UNION ALL\n" + " SELECT dt + INTERVAl 1 DAY FROM all_dates WHERE dt + INTERVAL 1 DAY <= CURRENT_TIMESTAMP()\n" + ")\n" + - "SELECT dates.dt date, COALESCE(t.total, 0) AS total FROM all_dates dates LEFT JOIN (SELECT DATE(time) AS date, COUNT(time) AS total FROM hypercube.support_sessions WHERE staff = ? GROUP BY DATE(time)) t ON t.date = dates.dt ORDER BY dates.dt", + "SELECT dates.dt date, COALESCE(t.total, 0) AS total FROM all_dates dates LEFT JOIN (SELECT DATE(time) AS date, COUNT(time) AS total FROM support_sessions WHERE staff = ? GROUP BY DATE(time)) t ON t.date = dates.dt ORDER BY dates.dt", (statement) -> { statement.setString(1, player); statement.setString(2, player); diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/SupportBadCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/SupportBadCommand.java index 1f2dbd4d..b8ad2cde 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/SupportBadCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/SupportBadCommand.java @@ -72,15 +72,15 @@ public void run(CommandEvent event) { new DatabaseQuery() .query(new BasicQuery("SELECT DISTINCT p.name, count " + "FROM (SELECT players.name" + - " FROM hypercube.ranks," + - " hypercube.players" + + " FROM ranks," + + " players" + " WHERE ranks.uuid = players.uuid" + " AND ranks.support >= 1" + " AND ranks.moderation = 0" + " AND ranks.administration = 0" + " AND players.uuid NOT IN (SELECT DISTINCT uuid FROM owen.excused_staff WHERE excused_till > CURRENT_TIMESTAMP())) p" + " LEFT OUTER JOIN (SELECT DISTINCT staff AS name, COUNT(staff) AS count" + - " FROM hypercube.support_sessions" + + " FROM support_sessions" + " WHERE time > CURRENT_TIMESTAMP() - INTERVAL ? DAY" + " GROUP BY staff) cn ON cn.name = p.name " + "WHERE cn.count < ?" + diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/SupportBannedPlayersCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/SupportBannedPlayersCommand.java index 790207b4..9b32e30e 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/SupportBannedPlayersCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/SupportBannedPlayersCommand.java @@ -46,8 +46,8 @@ public void run(CommandEvent event) { ); new DatabaseQuery() - .query(new BasicQuery("SELECT support_bans.uuid, p.name, support_bans.reason FROM hypercube.support_bans" + - " LEFT JOIN hypercube.players p ON support_bans.uuid = p.uuid")) + .query(new BasicQuery("SELECT support_bans.uuid, p.name, support_bans.reason FROM support_bans" + + " LEFT JOIN players p ON support_bans.uuid = p.uuid")) .compile() .run((result) -> { // Select unique names. diff --git a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/SupporteeSessionsCommand.java b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/SupporteeSessionsCommand.java index bc292fb7..fb885485 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/SupporteeSessionsCommand.java +++ b/src/main/java/com/diamondfire/helpbot/bot/command/impl/stats/support/SupporteeSessionsCommand.java @@ -30,7 +30,7 @@ public HelpContext getHelpContext() { protected List getSessions(String player) { List sessions = new ArrayList<>(); new DatabaseQuery() - .query(new BasicQuery("SELECT * FROM hypercube.support_sessions WHERE name = ? ORDER BY time", (statement) -> statement.setString(1, player))) + .query(new BasicQuery("SELECT * FROM support_sessions WHERE name = ? ORDER BY time", (statement) -> statement.setString(1, player))) .compile() .run((result) -> { for (ResultSet set : result) { diff --git a/src/main/java/com/diamondfire/helpbot/bot/events/CommandEvent.java b/src/main/java/com/diamondfire/helpbot/bot/events/CommandEvent.java index 2f80e25f..de911cae 100644 --- a/src/main/java/com/diamondfire/helpbot/bot/events/CommandEvent.java +++ b/src/main/java/com/diamondfire/helpbot/bot/events/CommandEvent.java @@ -47,9 +47,8 @@ public void reply(PresetBuilder preset) { replyHandler.reply(preset, getChannel()); } - @SuppressWarnings("unchecked") public T getArgument(String code) { - return (T) parsedArgumentSet.getArgument(code); + return parsedArgumentSet.getArgument(code); } public Map getArguments() { diff --git a/src/main/java/com/diamondfire/helpbot/df/creator/requirements/DynamicRequirementProvider.java b/src/main/java/com/diamondfire/helpbot/df/creator/requirements/DynamicRequirementProvider.java index b38d5b36..62b7c271 100644 --- a/src/main/java/com/diamondfire/helpbot/df/creator/requirements/DynamicRequirementProvider.java +++ b/src/main/java/com/diamondfire/helpbot/df/creator/requirements/DynamicRequirementProvider.java @@ -17,7 +17,7 @@ public DynamicRequirementProvider(String identifier) { @Override public int getRequirement() { DatabaseResult result = new DatabaseQuery() - .query(new BasicQuery("SELECT req FROM hypercube.creator_req WHERE tier = ?", (statement) -> statement.setString(1, identifier))) + .query(new BasicQuery("SELECT req FROM creator_req WHERE tier = ?", (statement) -> statement.setString(1, identifier))) .compile().get(); try { diff --git a/src/main/java/com/diamondfire/helpbot/sys/graph/generators/GraphGenerator.java b/src/main/java/com/diamondfire/helpbot/sys/graph/generators/GraphGenerator.java index d4c981bd..d007bd74 100644 --- a/src/main/java/com/diamondfire/helpbot/sys/graph/generators/GraphGenerator.java +++ b/src/main/java/com/diamondfire/helpbot/sys/graph/generators/GraphGenerator.java @@ -2,8 +2,8 @@ import java.io.File; -public interface GraphGenerator { +public interface GraphGenerator { - File createGraph(TimeMode timeMode, int duration); + File createGraph(T context); } diff --git a/src/main/java/com/diamondfire/helpbot/sys/graph/generators/GraphGenerators.java b/src/main/java/com/diamondfire/helpbot/sys/graph/generators/GraphGenerators.java index 4a904ccb..57a6e823 100644 --- a/src/main/java/com/diamondfire/helpbot/sys/graph/generators/GraphGenerators.java +++ b/src/main/java/com/diamondfire/helpbot/sys/graph/generators/GraphGenerators.java @@ -2,14 +2,20 @@ public interface GraphGenerators { - GraphGenerator UNIQUE_JOINS = new QueryGraphGenerator("unique player joins", "" + - "SELECT time, COUNT(*) AS count FROM (SELECT DISTINCT uuid, DATE_FORMAT(time, ?) AS time " + - "FROM hypercube.player_join_log WHERE time > CURRENT_TIMESTAMP() - INTERVAL ? HOUR AND uuid NOT IN (SELECT uuid FROM litebans.bans WHERE active = 1 AND until = -1)) a " + - "GROUP BY time;"); + QueryGraphGenerator UNIQUE_JOINS = new QueryGraphGenerator("unique player joins", "" + + "SELECT time, COUNT(*) AS count " + + "FROM (SELECT DISTINCT uuid, DATE_FORMAT(time, ?) AS time" + + " FROM player_join_log" + + " WHERE time > ((NOW() - INTERVAL ? HOUR) - INTERVAL MINUTE(NOW()) MINUTE) - INTERVAL SECOND(NOW()) SECOND" + + " AND uuid NOT IN (SELECT uuid FROM litebans.bans WHERE active = 1 AND until = -1)) a " + + "GROUP BY time"); - GraphGenerator NEW_PLAYERS = new QueryGraphGenerator("new player joins", "" + - "SELECT time, COUNT(*) AS count FROM (SELECT DISTINCT uuid, DATE_FORMAT(time, ?) AS time " + - "FROM hypercube.approved_users WHERE time > CURRENT_TIMESTAMP() - INTERVAL ? HOUR AND uuid NOT IN (SELECT uuid FROM litebans.bans WHERE active = 1 AND until = -1)) a " + - "GROUP BY time;"); + QueryGraphGenerator NEW_PLAYERS = new QueryGraphGenerator("new player joins", "" + + "SELECT time, COUNT(*) AS count " + + "FROM (SELECT DISTINCT uuid, DATE_FORMAT(time, ?) AS time" + + " FROM approved_users" + + " WHERE time > ((NOW() - INTERVAL ? HOUR) - INTERVAL MINUTE(NOW()) MINUTE) - INTERVAL SECOND(NOW()) SECOND" + + " AND uuid NOT IN (SELECT uuid FROM litebans.bans WHERE active = 1 AND until = -1)) a " + + "GROUP BY time"); } diff --git a/src/main/java/com/diamondfire/helpbot/sys/graph/generators/QueryGraphGenerator.java b/src/main/java/com/diamondfire/helpbot/sys/graph/generators/QueryGraphGenerator.java index c49a0995..96d63468 100644 --- a/src/main/java/com/diamondfire/helpbot/sys/graph/generators/QueryGraphGenerator.java +++ b/src/main/java/com/diamondfire/helpbot/sys/graph/generators/QueryGraphGenerator.java @@ -2,6 +2,7 @@ import com.diamondfire.helpbot.sys.database.impl.DatabaseQuery; import com.diamondfire.helpbot.sys.database.impl.queries.BasicQuery; +import com.diamondfire.helpbot.sys.graph.generators.context.TimeGraphContext; import com.diamondfire.helpbot.sys.graph.graphable.*; import com.diamondfire.helpbot.sys.graph.impl.ChartGraphBuilder; import org.intellij.lang.annotations.Language; @@ -10,7 +11,7 @@ import java.sql.ResultSet; import java.util.*; -public class QueryGraphGenerator implements GraphGenerator { +public class QueryGraphGenerator implements GraphGenerator { private final String title; @Language("SQL") @@ -22,14 +23,15 @@ public QueryGraphGenerator(String title, @Language("SQL") String query) { } @Override - public File createGraph(TimeMode timeMode, int duration) { + public File createGraph(TimeGraphContext context) { Map, Integer> entries = new LinkedHashMap<>(); ChartGraphBuilder builder = new ChartGraphBuilder(); + TimeMode timeMode = context.getMode(); new DatabaseQuery() .query(new BasicQuery(query, statement -> { statement.setString(1, timeMode.getDateFormat()); - statement.setInt(2, timeMode.getUnitConversion().apply(duration)); + statement.setInt(2, timeMode.getUnitConversion().apply(context.getNum())); })) .compile() .run((result) -> { diff --git a/src/main/java/com/diamondfire/helpbot/sys/graph/generators/TimeMode.java b/src/main/java/com/diamondfire/helpbot/sys/graph/generators/TimeMode.java index 6135bdeb..3976cf06 100644 --- a/src/main/java/com/diamondfire/helpbot/sys/graph/generators/TimeMode.java +++ b/src/main/java/com/diamondfire/helpbot/sys/graph/generators/TimeMode.java @@ -5,7 +5,7 @@ public enum TimeMode { - HOURLY("Hourly", "%d-%Hh", (num) -> num), + HOURLY("Hourly", "%m-%d-%Hh", (num) -> num), DAILY("Daily", "%y-%m-%d", (num) -> (int) TimeUnit.DAYS.toHours(num)), WEEKLY("Weekly", "%y-%m-%v", (num) -> (int) TimeUnit.DAYS.toHours(num * 7L)), MONTHLY("Monthly", "%y-%m", (num) -> (int) TimeUnit.DAYS.toHours(num * 30L)), diff --git a/src/main/java/com/diamondfire/helpbot/sys/graph/generators/context/SupportGraphContext.java b/src/main/java/com/diamondfire/helpbot/sys/graph/generators/context/SupportGraphContext.java new file mode 100644 index 00000000..4f547c7b --- /dev/null +++ b/src/main/java/com/diamondfire/helpbot/sys/graph/generators/context/SupportGraphContext.java @@ -0,0 +1,17 @@ +package com.diamondfire.helpbot.sys.graph.generators.context; + +import com.diamondfire.helpbot.sys.graph.generators.TimeMode; + +public class SupportGraphContext extends TimeGraphContext { + + private final String support; + + public SupportGraphContext(TimeMode mode, int num, String support) { + super(mode, num); + this.support = support; + } + + public String getSupport() { + return support; + } +} diff --git a/src/main/java/com/diamondfire/helpbot/sys/graph/generators/context/TimeGraphContext.java b/src/main/java/com/diamondfire/helpbot/sys/graph/generators/context/TimeGraphContext.java new file mode 100644 index 00000000..d20206bb --- /dev/null +++ b/src/main/java/com/diamondfire/helpbot/sys/graph/generators/context/TimeGraphContext.java @@ -0,0 +1,22 @@ +package com.diamondfire.helpbot.sys.graph.generators.context; + +import com.diamondfire.helpbot.sys.graph.generators.TimeMode; + +public class TimeGraphContext { + + private final TimeMode mode; + private final int num; + + public TimeGraphContext(TimeMode mode, int num) { + this.mode = mode; + this.num = num; + } + + public TimeMode getMode() { + return mode; + } + + public int getNum() { + return num; + } +} diff --git a/src/main/java/com/diamondfire/helpbot/sys/tasks/impl/GraphChannelTask.java b/src/main/java/com/diamondfire/helpbot/sys/tasks/impl/GraphChannelTask.java index 0f62b059..62182dfd 100644 --- a/src/main/java/com/diamondfire/helpbot/sys/tasks/impl/GraphChannelTask.java +++ b/src/main/java/com/diamondfire/helpbot/sys/tasks/impl/GraphChannelTask.java @@ -3,6 +3,7 @@ import com.diamondfire.helpbot.bot.HelpBotInstance; import com.diamondfire.helpbot.bot.command.impl.stats.graph.*; import com.diamondfire.helpbot.sys.graph.generators.*; +import com.diamondfire.helpbot.sys.graph.generators.context.TimeGraphContext; import com.diamondfire.helpbot.sys.tasks.MidnightTask; import net.dv8tion.jda.api.entities.TextChannel; @@ -13,7 +14,8 @@ public void run() { TextChannel channel = HelpBotInstance.getJda().getTextChannelById(736019542882517062L); channel.getHistoryFromBeginning(50).queue(messageHistory -> channel.purgeMessages(messageHistory.getRetrievedHistory())); - channel.sendFile(GraphGenerators.NEW_PLAYERS.createGraph(TimeMode.DAILY, 14)).queue(); - channel.sendFile(GraphGenerators.UNIQUE_JOINS.createGraph(TimeMode.DAILY, 14)).queue(); + TimeGraphContext context = new TimeGraphContext(TimeMode.DAILY, 14); + channel.sendFile(GraphGenerators.NEW_PLAYERS.createGraph(context)).queue(); + channel.sendFile(GraphGenerators.UNIQUE_JOINS.createGraph(context)).queue(); } } diff --git a/src/main/java/com/diamondfire/helpbot/sys/tasks/impl/RefreshCreditsTask.java b/src/main/java/com/diamondfire/helpbot/sys/tasks/impl/RefreshCreditsTask.java index 83269831..3bd36086 100644 --- a/src/main/java/com/diamondfire/helpbot/sys/tasks/impl/RefreshCreditsTask.java +++ b/src/main/java/com/diamondfire/helpbot/sys/tasks/impl/RefreshCreditsTask.java @@ -16,6 +16,6 @@ public void run() { new DatabaseQuery() .query(new BasicQuery("INSERT INTO owen.creator_rankings_log(uuid, points, `rank`, date) " + - "SELECT uuid, points, cur_rank, CURRENT_DATE() FROM hypercube.creator_rankings WHERE points > 4990;")).compile(); + "SELECT uuid, points, cur_rank, CURRENT_DATE() FROM creator_rankings WHERE points > 4990;")).compile(); } } diff --git a/src/main/java/com/diamondfire/helpbot/sys/tasks/impl/SupportUnexcuseTask.java b/src/main/java/com/diamondfire/helpbot/sys/tasks/impl/SupportUnexcuseTask.java index ae68adf6..65d62c04 100644 --- a/src/main/java/com/diamondfire/helpbot/sys/tasks/impl/SupportUnexcuseTask.java +++ b/src/main/java/com/diamondfire/helpbot/sys/tasks/impl/SupportUnexcuseTask.java @@ -44,7 +44,7 @@ public void run() { TextChannel channel = HelpBotInstance.getJda().getTextChannelById(EXPERT_CHAT); new DatabaseQuery() - .query(new BasicQuery("SELECT * FROM hypercube.players WHERE players.uuid = ?", (statement) -> statement.setString(1, uuid))) + .query(new BasicQuery("SELECT * FROM players WHERE players.uuid = ?", (statement) -> statement.setString(1, uuid))) .compile() .run((result) -> { EmbedBuilder embed = builder.getEmbed(); @@ -79,7 +79,7 @@ public static void prepare() { " excused_till," + " reason " + "FROM owen.excused_staff " + - "LEFT JOIN hypercube.ranks r ON excused_staff.uuid = r.uuid " + + "LEFT JOIN ranks r ON excused_staff.uuid = r.uuid " + "WHERE (support > 0 || moderation > 0) AND (excused_till > CURRENT_TIMESTAMP() || !handled) " + "ORDER BY excused_till DESC;")) .compile() diff --git a/src/main/java/com/diamondfire/helpbot/util/Util.java b/src/main/java/com/diamondfire/helpbot/util/Util.java index 9f23bdf3..65c5cf06 100644 --- a/src/main/java/com/diamondfire/helpbot/util/Util.java +++ b/src/main/java/com/diamondfire/helpbot/util/Util.java @@ -116,7 +116,7 @@ public static void updateGuild(Guild guild) { HashMap accounts = new HashMap<>(); new DatabaseQuery() - .query(new BasicQuery("SELECT discord_id AS discord_id, player_name AS player FROM hypercube.linked_accounts WHERE discord_id IS NOT NULL AND player_name IS NOT NULL;")) + .query(new BasicQuery("SELECT discord_id AS discord_id, player_name AS player FROM linked_accounts WHERE discord_id IS NOT NULL AND player_name IS NOT NULL;")) .compile() .run((result) -> { for (ResultSet set : result) { @@ -177,7 +177,7 @@ public static void updateMember(Member member, String verifyName, Role verifiedR public static void updateMember(Member member) { new DatabaseQuery() - .query(new BasicQuery("SELECT player_name AS name FROM hypercube.linked_accounts WHERE discord_id = ?;", (statement) -> { + .query(new BasicQuery("SELECT player_name AS name FROM linked_accounts WHERE discord_id = ?;", (statement) -> { statement.setLong(1, member.getIdLong()); })) .compile() diff --git a/src/main/java/com/diamondfire/helpbot/util/nbs/CompressionUtil.java b/src/main/java/com/diamondfire/helpbot/util/nbs/CompressionUtil.java new file mode 100644 index 00000000..76feef15 --- /dev/null +++ b/src/main/java/com/diamondfire/helpbot/util/nbs/CompressionUtil.java @@ -0,0 +1,47 @@ +package com.diamondfire.helpbot.util.nbs; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.zip.*; +//from https://github.com/CodeUtilities/CodeUtilities + +public class CompressionUtil { + + public static byte[] fromBase64(byte[] bytes) { + return Base64.getDecoder().decode(bytes); + } + + public static byte[] toBase64(byte[] bytes) { + return Base64.getEncoder().encode(bytes); + } + + public static byte[] fromGZIP(byte[] bytes) throws IOException { + if (bytes == null) { + return null; + } + + GZIPInputStream gis = new GZIPInputStream(new ByteArrayInputStream(bytes)); + BufferedReader bf = new BufferedReader(new InputStreamReader(gis, StandardCharsets.UTF_8)); + StringBuilder outStr = new StringBuilder(); + String line; + while ((line = bf.readLine()) != null) { + outStr.append(line); + } + + return outStr.toString().getBytes(); + } + + public static byte[] toGZIP(byte[] bytes) throws IOException { + if (bytes == null) { + return null; + } + ByteArrayOutputStream obj = new ByteArrayOutputStream(); + GZIPOutputStream gzip = new GZIPOutputStream(obj); + gzip.write(bytes); + gzip.close(); + + return obj.toByteArray(); + } + +} diff --git a/src/main/java/com/diamondfire/helpbot/util/nbs/NBSDecoder.java b/src/main/java/com/diamondfire/helpbot/util/nbs/NBSDecoder.java new file mode 100644 index 00000000..a38628cf --- /dev/null +++ b/src/main/java/com/diamondfire/helpbot/util/nbs/NBSDecoder.java @@ -0,0 +1,277 @@ +package com.diamondfire.helpbot.util.nbs; + +import java.io.*; +import java.math.BigDecimal; +//from https://github.com/CodeUtilities/CodeUtilities + +public class NBSDecoder { + + public static SongData parse(File songFile) throws IOException, OutdatedNBSException { + try { + return parse(new FileInputStream(songFile), songFile); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + return null; + } + + private static SongData parse(InputStream inputStream, File songFile) throws IOException, OutdatedNBSException { + String title = ""; + String author = ""; + String file = songFile.getName(); + float speed = 0f; + float actualSpeed = 0f; + short timeSignature = 4; + int loopTick = 0; + int loopCount = 0; + int vanillaInstruments = 9; + + StringBuilder stringBuilder = new StringBuilder(); + StringBuilder layerStringBuilder = new StringBuilder(); + + DataInputStream dataInputStream = new DataInputStream(inputStream); + short length = readShort(dataInputStream); + int nbsversion = 0; + if (length == 0) { + nbsversion = dataInputStream.readByte(); + vanillaInstruments = dataInputStream.readByte(); + if (nbsversion >= 3) { + length = readShort(dataInputStream); + } else if (nbsversion == 1 || nbsversion == 2) { + throw new OutdatedNBSException(); + } + } else { + + } + short layers = readShort(dataInputStream); //song height + title = readString(dataInputStream); //title + author = readString(dataInputStream); //author + readString(dataInputStream); //original author + String description = readString(dataInputStream); //description + actualSpeed = readShort(dataInputStream); //speed + speed = actualSpeed / 100f; //speed + dataInputStream.readBoolean(); //autosave + dataInputStream.readByte(); //autosave duration + timeSignature = (short) dataInputStream.readByte(); //time signature + readInt(dataInputStream); //minutes spent + readInt(dataInputStream); //left clicks + readInt(dataInputStream); //right clicks + readInt(dataInputStream); //blocks added + readInt(dataInputStream); //nlocks removed + readString(dataInputStream); // mid or schematic filename + if (nbsversion >= 4) { + dataInputStream.readByte(); //loop on/off + loopCount = dataInputStream.readByte(); //loop count + loopTick = readShort(dataInputStream); //loop start tick + } + + short tick = -1; + String[][] addStringList = new String[layers][length + 1]; + int[][] instrumentList = new int[layers][length + 1]; + int[][] pitchList = new int[layers][length + 1]; + int[][] finepitchList = new int[layers][length + 1]; + int[][] velocityList = new int[layers][length + 1]; + int[][] panningList = new int[layers][length + 1]; + boolean[] columnExistence = new boolean[length + 1]; + boolean[][] noteExistence = new boolean[layers][length + 1]; + boolean firstNoted = false; + + while (true) { //Read notes + short t = readShort(dataInputStream); + if (t == 0) { + break; + } + tick += t; + + columnExistence[tick] = true; + + short layer = -1; + while (true) { + short jumpLayers = readShort(dataInputStream); + if (jumpLayers == 0) { + break; + } + layer += jumpLayers; + byte instrument = dataInputStream.readByte(); + byte note = dataInputStream.readByte(); + byte velocity = 100; + int panning = 100; + short finepitch = 0; + if (nbsversion >= 4) { + velocity = dataInputStream.readByte(); + panning = Byte.toUnsignedInt(dataInputStream.readByte()); + finepitch = readShort(dataInputStream); + } + + + + instrumentList[layer][tick] = instrument; + pitchList[layer][tick] = note; + finepitchList[layer][tick] = finepitch; + velocityList[layer][tick] = velocity; + panningList[layer][tick] = panning; + noteExistence[layer][tick] = true; + } + } + + for (int i = 0; i < layers; i++) { //Read layer data + + String name = readString(dataInputStream); + + if (nbsversion >= 4) { + dataInputStream.readByte(); + } + + byte volume = dataInputStream.readByte(); + int panning = 100; + + if (nbsversion >= 2) { + panning = Byte.toUnsignedInt(dataInputStream.readByte()); + } + + for (int currentTick = 0; currentTick < length + 1; currentTick++) { + boolean noteExists = noteExistence[i][currentTick]; + if (noteExists == true) { + + int noteVelocity = velocityList[i][currentTick]; + int notePanning = panningList[i][currentTick]; + + double averageVelocity = noteVelocity * (volume / 100d); + double averagePanning = (notePanning + panning) / 2d; + + double preFinalPanning = (averagePanning - 100) / 50; + + String finalVelocity = new BigDecimal(averageVelocity).setScale(3, BigDecimal.ROUND_FLOOR).stripTrailingZeros().toPlainString(); + String finalPanning = new BigDecimal(preFinalPanning).setScale(3, BigDecimal.ROUND_FLOOR).stripTrailingZeros().toPlainString(); + + + + String finalString; + if (preFinalPanning == 0) { + finalString = "," + finalVelocity; + } else { + finalString = "," + finalVelocity + "," + finalPanning; + } + addStringList[i][currentTick] = finalString; + } + } + + String finalLayerVolume = new BigDecimal(volume).setScale(3, BigDecimal.ROUND_FLOOR).stripTrailingZeros().toPlainString(); + String finalLayerPanning = new BigDecimal(panning).setScale(3, BigDecimal.ROUND_FLOOR).stripTrailingZeros().toPlainString(); + + layerStringBuilder.append("=" + finalLayerVolume + "," + finalLayerPanning); + } + + int customInstruments = 0; + customInstruments = dataInputStream.readByte(); + + int[] customPitchList = new int[customInstruments]; + + if (customInstruments >= 1) { + for (int i = 0; i < customInstruments; i++) { + int instrumentOffset = vanillaInstruments + customInstruments; + int instrumentPitch = 0; + + readString(dataInputStream); //Instrument name + readString(dataInputStream); //Sound file + + instrumentPitch = dataInputStream.readByte(); //Sound pitch + + customPitchList[i] = instrumentPitch; + + dataInputStream.readByte(); //Press key + } + } + + + + dataInputStream.close(); + + for (int currentTick = 0; currentTick < length + 1; currentTick++) { + boolean columnExists = columnExistence[currentTick]; + if (columnExists == true) { + StringBuilder columnStringBuilder = new StringBuilder(); + if (!firstNoted) { + columnStringBuilder.append(currentTick + 1); + firstNoted = true; + } else { + columnStringBuilder.append("=" + (currentTick + 1)); + } + boolean firstAppend = true; + for (int i = 0; i < layers; i++) { + boolean noteExists = noteExistence[i][currentTick]; + if (noteExists == true) { + String laterNoteString = addStringList[i][currentTick]; + + int noteInstrument = instrumentList[i][currentTick]; + int noteKey = pitchList[i][currentTick]; + int noteFinePitch = finepitchList[i][currentTick]; + int noteKeyOffset = 0; + + + + if (noteInstrument >= vanillaInstruments) { + int instrumentId = noteInstrument - vanillaInstruments; + noteKeyOffset = customPitchList[instrumentId] - 45; + } + if (firstAppend == true) { + columnStringBuilder.append(":" + (noteInstrument + 1) + "," + getMinecraftPitch(noteKey + (double) noteFinePitch / 100d, noteKeyOffset) + laterNoteString); + firstAppend = false; + } else { + columnStringBuilder.append(";" + (noteInstrument + 1) + "," + getMinecraftPitch(noteKey + (double) noteFinePitch / 100d, noteKeyOffset) + laterNoteString); + } + } + } + stringBuilder.append(columnStringBuilder.toString()); + } + } + + + + return new SongData(title, author, speed, (int) ((Math.ceil((length + 1) / timeSignature) + 1) * timeSignature), stringBuilder.toString(), file, layerStringBuilder.toString(), (loopTick + 1), loopCount, customInstruments); + } + + private static short readShort(DataInputStream dataInputStream) throws IOException { + int byte1 = dataInputStream.readUnsignedByte(); + int byte2 = dataInputStream.readUnsignedByte(); + return (short) (byte1 + (byte2 << 8)); + } + + private static int readInt(DataInputStream dataInputStream) throws IOException { + int byte1 = dataInputStream.readUnsignedByte(); + int byte2 = dataInputStream.readUnsignedByte(); + int byte3 = dataInputStream.readUnsignedByte(); + int byte4 = dataInputStream.readUnsignedByte(); + return (byte1 + (byte2 << 8) + (byte3 << 16) + (byte4 << 24)); + } + + private static String readString(DataInputStream dataInputStream) throws IOException { + int length = readInt(dataInputStream); + StringBuilder builder = new StringBuilder(length); + for (; length > 0; --length) { + char c = (char) dataInputStream.readByte(); + if (c == (char) 0x0D) { + c = ' '; + } + builder.append(c); + } + return builder.toString(); + } + + private static int getMinecraftPitch(double key, double offset) { + + if (key < 33) key -= 9; + else if (key > 57) key -= 57; + else key -= 33; + + key += offset; + + double finalValue = (0.5 * (Math.pow(2, (key / 12)))) * 1000; + + return (int) finalValue; + } + + public SongData parse(InputStream inputStream) throws IOException, OutdatedNBSException { + return parse(inputStream, null); + } +} diff --git a/src/main/java/com/diamondfire/helpbot/util/nbs/NBSToTemplate.java b/src/main/java/com/diamondfire/helpbot/util/nbs/NBSToTemplate.java new file mode 100644 index 00000000..6eee3ec0 --- /dev/null +++ b/src/main/java/com/diamondfire/helpbot/util/nbs/NBSToTemplate.java @@ -0,0 +1,159 @@ +package com.diamondfire.helpbot.util.nbs; + +import java.math.BigDecimal; +// from https://github.com/CodeUtilities/CodeUtilities + + + +public class NBSToTemplate { + + private static final String SONG_PARSER_VERSION = "4"; + private static final String SONG_NBS_FORMAT_VERSION = "4"; + + String song; + String name; + String author; + String filename; + String layers; + String version; + float speed; + int length; + int loopTick; + int loopCount; + int customInstrumentCount; + boolean multipleChests = false; + + public NBSToTemplate(SongData song) { + + this.version = "v" + SONG_PARSER_VERSION + "-nbs" + SONG_NBS_FORMAT_VERSION; + + this.song = song.getNotes(); + this.author = song.getAuthor(); + this.name = song.getName(); + this.filename = song.getFileName(); + this.layers = song.getLayers(); + this.length = song.getLength(); + this.speed = song.getSpeed(); + this.loopTick = song.getLoopTick(); + this.loopCount = song.getLoopCount(); + this.customInstrumentCount = song.getCustomInstrumentCount(); + } + + public String convert() { + String[] songData = song.split("="); + StringBuilder currentNotes = new StringBuilder(); + StringBuilder code = new StringBuilder(); + StringBuilder currentBlock = new StringBuilder(); + StringBuilder instList = new StringBuilder(); + + String songTempo = new BigDecimal(this.speed).stripTrailingZeros().toPlainString(); + + if (name.length() == 0) { + if (filename.indexOf(".") > 0) { + name = filename.substring(0, filename.lastIndexOf(".")); + } else { + name = filename; + } + } + if (author.length() == 0) author = "N/A"; + + code.append(String.format("{\"id\":\"block\",\"block\":\"func\",\"args\":{\"items\":[{\"item\":{\"id\":\"bl_tag\",\"data\":{\"option\":\"False\",\"tag\":\"Is Hidden\",\"action\":\"dynamic\",\"block\":\"func\"}},\"slot\":26}]},\"data\":\"%s\"},", name)); + + int slot = 1; + int chestCount = 1; + boolean chestInited = false; + int noteCount = 0; + boolean finalNote = false; + + for (int i = 0; i < songData.length; i++) { + boolean closeChest = false; + if (slot == 1) { + if (!chestInited) { + chestInited = true; + currentBlock.append("{\"id\":\"block\",\"block\":\"set_var\",\"args\":{\"items\":[{\"item\":{\"id\":\"var\",\"data\":{\"name\":\"notes\",\"scope\":\"local\"}},\"slot\":0}"); + } + } + + if (slot >= 27) { + closeChest = true; + } + + if (!closeChest) { + String currentNote = songData[i]; + String revertString = currentNotes.toString(); + + if (noteCount == 0) { + currentNotes.append(currentNote); + } else { + currentNotes.append("=" + currentNote); + } + noteCount++; + + if (currentNotes.length() > 1930) { + currentNotes = new StringBuilder(revertString); + currentBlock.append(String.format(",{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"%s\"}},\"slot\":%d}", currentNotes.toString(), slot)); + currentNotes.setLength(0); + noteCount = 0; + finalNote = true; + i -= 1; + slot++; + } + + if (i >= songData.length - 1) { + if (!finalNote) { + currentBlock.append(String.format(",{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"%s\"}},\"slot\":%d}", currentNotes.toString(), slot)); + currentNotes.setLength(0); + } + closeChest = true; + } + finalNote = false; + } + if (closeChest) { + String varActionType; + if (chestCount == 1) { + varActionType = "CreateList"; + } else { + varActionType = "AppendValue"; + } + + currentBlock.append(String.format("]},\"action\":\"%s\"},", varActionType)); + code.append(currentBlock.toString()); + currentBlock.setLength(0); + currentNotes.setLength(0); + + chestInited = false; + noteCount = 0; + finalNote = false; + chestCount++; + closeChest = false; + slot = 1; + } + } + + //CreateList: instrumentNames + if (customInstrumentCount == 0) { + code.append("{\"id\":\"block\",\"block\":\"set_var\",\"args\":{\"items\":[{\"item\":{\"id\":\"var\",\"data\":{\"name\":\"instrumentNames\",\"scope\":\"local\"}},\"slot\":0},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Harp\"}},\"slot\":1},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Bass\"}},\"slot\":2},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Bass Drum\"}},\"slot\":3},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Snare Drum\"}},\"slot\":4},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Click\"}},\"slot\":5},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Guitar\"}},\"slot\":6},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Flute\"}},\"slot\":7},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Bell\"}},\"slot\":8},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Chime\"}},\"slot\":9},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Xylophone\"}},\"slot\":10},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Iron Xylophone\"}},\"slot\":11},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Cow Bell\"}},\"slot\":12},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Didgeridoo\"}},\"slot\":13},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Bit\"}},\"slot\":14},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Banjo\"}},\"slot\":15},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Pling\"}},\"slot\":16}]},\"action\":\"CreateList\"},"); + } else { + instList.append("{\"id\":\"block\",\"block\":\"set_var\",\"args\":{\"items\":[{\"item\":{\"id\":\"var\",\"data\":{\"name\":\"instrumentNames\",\"scope\":\"local\"}},\"slot\":0},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Harp\"}},\"slot\":1},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Bass\"}},\"slot\":2},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Bass Drum\"}},\"slot\":3},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Snare Drum\"}},\"slot\":4},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Click\"}},\"slot\":5},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Guitar\"}},\"slot\":6},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Flute\"}},\"slot\":7},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Bell\"}},\"slot\":8},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Chime\"}},\"slot\":9},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Xylophone\"}},\"slot\":10},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Iron Xylophone\"}},\"slot\":11},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Cow Bell\"}},\"slot\":12},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Didgeridoo\"}},\"slot\":13},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Bit\"}},\"slot\":14},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Banjo\"}},\"slot\":15},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"Pling\"}},\"slot\":16},"); + + int currentSlot; + + currentSlot = 17; + for (int currentInstID = 1; currentInstID <= customInstrumentCount; currentInstID++) { + if (currentInstID == customInstrumentCount) { + instList.append(String.format("{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"\"}},\"slot\":%d}", currentInstID, currentSlot)); + } else { + instList.append(String.format("{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"\"}},\"slot\":%d},", currentInstID, currentSlot)); + } + currentSlot++; + } + instList.append("]},\"action\":\"CreateList\"},"); + code.append(instList.toString()); + } + + //CreateList: songData + code.append(String.format("{\"id\":\"block\",\"block\":\"set_var\",\"args\":{\"items\":[{\"item\":{\"id\":\"var\",\"data\":{\"name\":\"songData\",\"scope\":\"local\"}},\"slot\":0},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"%s\"}},\"slot\":1},{\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"%s\"}},\"slot\":2},{\"item\":{\"id\":\"num\",\"data\":{\"name\":\"%s\"}},\"slot\":3}, {\"item\":{\"id\":\"num\",\"data\":{\"name\":\"%d\"}},\"slot\":4}, {\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"%s\"}},\"slot\":5}, {\"item\":{\"id\":\"txt\",\"data\":{\"name\":\"%s\"}},\"slot\":6},{\"item\":{\"id\":\"num\",\"data\":{\"name\":\"%d\"}},\"slot\":7},{\"item\":{\"id\":\"num\",\"data\":{\"name\":\"%d\"}},\"slot\":8}]},\"action\":\"CreateList\"}", name, author, songTempo, length, layers, version, loopTick, loopCount)); + + return "{\"blocks\": [" + code + "]}"; + } +} diff --git a/src/main/java/com/diamondfire/helpbot/util/nbs/OutdatedNBSException.java b/src/main/java/com/diamondfire/helpbot/util/nbs/OutdatedNBSException.java new file mode 100644 index 00000000..1c4245c8 --- /dev/null +++ b/src/main/java/com/diamondfire/helpbot/util/nbs/OutdatedNBSException.java @@ -0,0 +1,4 @@ +package com.diamondfire.helpbot.util.nbs; +//from https://github.com/CodeUtilities/CodeUtilities +public class OutdatedNBSException extends Exception{ +} diff --git a/src/main/java/com/diamondfire/helpbot/util/nbs/SongData.java b/src/main/java/com/diamondfire/helpbot/util/nbs/SongData.java new file mode 100644 index 00000000..ad939a07 --- /dev/null +++ b/src/main/java/com/diamondfire/helpbot/util/nbs/SongData.java @@ -0,0 +1,88 @@ +package com.diamondfire.helpbot.util.nbs; +// from https://github.com/CodeUtilities/CodeUtilities +public class SongData { + + String name; + String author; + float speed; + int length; + String fileName; + String notes; + String layers; + int loopTick; + int loopCount; + int customInstrumentCount; + + public SongData(String name, String author, float speed, int length, String notes, String fileName, String layers, int loopTick, int loopCount, int customInstrumentCount) { + this.name = name; + this.author = author; + this.speed = speed; + this.length = length; + this.notes = notes; + this.fileName = fileName; + this.layers = layers; + this.loopTick = loopTick; + this.loopCount = loopCount; + this.customInstrumentCount = customInstrumentCount; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public float getSpeed() { + return speed; + } + + public void setSpeed(float speed) { + this.speed = speed; + } + + public int getLength() { + return length; + } + + public String getNotes() { + return notes; + } + + public void setNotes(String notes) { + this.notes = notes; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getLayers() { + return layers; + } + + public int getLoopTick() { + return loopTick; + } + + public int getLoopCount() { + return loopCount; + } + + public int getCustomInstrumentCount() { + return customInstrumentCount; + } +} \ No newline at end of file