Page MenuHomedesp's stash

No OneTemporary

diff --git a/src/me/despawningbone/discordbot/command/anime/Sauce.java b/src/me/despawningbone/discordbot/command/anime/Sauce.java
index f29106c..3ce28ff 100644
--- a/src/me/despawningbone/discordbot/command/anime/Sauce.java
+++ b/src/me/despawningbone/discordbot/command/anime/Sauce.java
@@ -1,166 +1,168 @@
package me.despawningbone.discordbot.command.anime;
import java.awt.Color;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import me.despawningbone.discordbot.command.Command;
import me.despawningbone.discordbot.command.CommandResult;
import me.despawningbone.discordbot.command.CommandResult.CommandResultType;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.User;
public class Sauce extends Command{
public Sauce() {
this.desc = "Get the source of an anime pic!";
- this.usage = "<url>";
+ this.usage = "[-d] [imgurl]";
this.alias = Arrays.asList("source", "saucenao", "iqdb");
+ this.remarks = Arrays.asList("The URL should be a direct link to an image.", "You can also upload an image as an attachment while calling this command instead of using a url.",
+ " * Specify the `-d` parameter to do a depth search!", " * It is useful for cropped images and edited images, but makes the search much longer.");
}
@Override
public CommandResult execute(TextChannel channel, User author, Message msg, String[] args) { //allow people to not input url to check sauce of the most recent image like u/2dgt3d?
List<String> amend = new ArrayList<String>(Arrays.asList(args));
int temp = amend.indexOf("-d");
if(temp != -1) amend.subList(temp, temp + 1).clear();
String url = null;
try {
if(amend.size() < 1) {
if(msg.getAttachments().size() > 0) url = msg.getAttachments().get(0).getUrl();
else throw new MalformedURLException();
} else {
url = amend.get(0).trim();
new URL(url);
}
} catch(MalformedURLException e) {
return new CommandResult(CommandResultType.FAILURE, "Please enter a valid URL!");
}
System.out.println(url);
try {
channel.sendTyping().queueAfter(20, TimeUnit.MILLISECONDS);
if(temp != -1) {
channel.sendMessage("Performing depth search for the picture... (this can take up to 20 seconds)").queue();
String[] urls = yandexSearch(url);
System.out.println(Arrays.asList(urls));
url = urls[2] == null ? urls[0] : urls[1] + ";" + urls[2];
//sync
//List<EmbedBuilder> collect = Arrays.asList(tempSearchSauce(urls[0]),tempSearchSauce(urls[1]));
//async
CompletableFuture<EmbedBuilder> first = CompletableFuture.supplyAsync(() -> {try {return tempSearchSauce(urls[0]);} catch (IOException e){e.printStackTrace(); return null;}});
CompletableFuture<EmbedBuilder> ratio = CompletableFuture.supplyAsync(() -> {try {return tempSearchSauce(urls[1]);} catch (IOException e){e.printStackTrace(); return null;}});
List<EmbedBuilder> collect = CompletableFuture.allOf(first, ratio)
.thenApply(future -> Arrays.asList(first.join(), ratio.join()))
.whenComplete((s, t) -> {if(!(ratio.join() != null && first.join() != null) && t != null) throw new CompletionException(t.getCause());}).get();
channel.sendMessage(collect.stream().filter(e -> e != null).sorted((a, b) -> urls[2] == null ? -1 : Double.compare(Double.parseDouble(b.build().getFooter().getText().replaceAll(".*?([.0-9]*%).*", "$1").replace("%", "")), Double.parseDouble(a.build().getFooter().getText().replaceAll(".*?([.0-9]*%).*", "$1").replace("%", "")))).findFirst().get().build()).queue();
} else {
EmbedBuilder eb = tempSearchSauce(url);
channel.sendMessage(eb.build()).queue();
}
} catch (IOException | InterruptedException | ExecutionException e) {
Throwable t = e instanceof ExecutionException ? e.getCause() : e;
return new CommandResult(CommandResultType.ERROR, ExceptionUtils.getStackTrace(t));
} catch (NullPointerException | NoSuchElementException e) {
if(e instanceof NoSuchElementException) {
EmbedBuilder eb = new EmbedBuilder();
String[] urls = url.split(";");
eb.setThumbnail(urls[0]);
eb.setTitle("Possibly related image", urls[0]);
eb.setDescription("Maybe [this](" + urls[urls.length > 1 ? 1 : 0] + ") will help in your search for the delicious marinara?");
channel.sendMessage(eb.build()).queueAfter(20, TimeUnit.MILLISECONDS);
}
return new CommandResult(CommandResultType.NORESULT);
}
return new CommandResult(CommandResultType.SUCCESS);
}
private String[] yandexSearch(String url) throws IOException {
Element yandex = Jsoup.connect("https://yandex.com/images/search?url=" + URLEncoder.encode(url, "UTF-8") + "&rpt=imageview").get().body();
String[] size = new String[]{yandex.selectFirst(".CbirPreview-Placeholder").attr("width"), yandex.selectFirst(".CbirPreview-Placeholder").attr("height")};
//double ratio = Double.parseDouble(size[0]) / Double.parseDouble(size[1]) >= 1 ? 16.0/9 : 9/16.0;
double ratio = Double.parseDouble(size[0]) / Double.parseDouble(size[1]);
System.out.println(yandex.select(".other-sites__thumb"));
System.out.println(size[0] + " " + size[1] + " " + ratio);
String other, site = null, similar = URLDecoder.decode(yandex.select(".cbir-similar__thumb .cbir-similar__image").get(yandex.select(".cbir-other-sizes__item").size() > 0 ? 1 : 0).parent().attr("href").split("img_url=")[1].split("&")[0], "UTF-8");
if(yandex.select(".cbir-other-sizes__list").size() > 0) { //TODO merge the sort algorithms?
/*other = yandex.select(".cbir-other-sizes__list").first().select("a").stream().sorted((a, b) -> { //selects largest possible section of the other sizes
String[] aA = a.select(".cbir-other-sizes__resolution").first().text().split("×"), bA = b.select(".cbir-other-sizes__resolution").first().text().split("×");
return Double.compare(Math.abs(Double.parseDouble(aA[0]) / Double.parseDouble(aA[1]) - ratio), Math.abs(Double.parseDouble(bA[0]) / Double.parseDouble(bA[1]) - ratio));
}).findFirst().get().attr("href");*/
other = yandex.select(".cbir-other-sizes__list a").first().attr("href"); //sorting with ratio seems to perform bad for most crops so dont sort anymore
} else {
yandex.select(".other-sites__item").stream().limit(12).sorted((a, b) -> {
String[] aA = a.select(".other-sites__meta").first().text().split("×"), bA = b.select(".other-sites__meta").first().text().split("×");
System.out.println(Math.abs(Double.parseDouble(aA[0]) / Double.parseDouble(aA[1]) - ratio) + ", " + Math.abs(Double.parseDouble(bA[0]) / Double.parseDouble(bA[1]) - ratio));
return Double.compare(Math.abs(Double.parseDouble(aA[0]) / Double.parseDouble(aA[1]) - ratio), Math.abs(Double.parseDouble(bA[0]) / Double.parseDouble(bA[1]) - ratio));}).forEach(s -> System.out.println(s));
Element eSite = yandex.select(".other-sites__item").stream().limit(12).sorted((a, b) -> {
String[] aA = a.select(".other-sites__meta").first().text().split("×"), bA = b.select(".other-sites__meta").first().text().split("×");
return Double.compare(Math.abs(Double.parseDouble(aA[0]) / Double.parseDouble(aA[1]) - ratio), Math.abs(Double.parseDouble(bA[0]) / Double.parseDouble(bA[1]) - ratio));}).findFirst().get();
other = eSite.select(".other-sites__preview-link").first().attr("href");
site = Jsoup.connect(eSite.select(".other-sites__snippet-site-link").first().attr("href")).get().html().split(";URL='")[1].split("'")[0];
}
return new String[]{similar, other, site};
//gets second image coz usually the first one is just a sharper identical image, then get the largest image that has the image inside or select an image closest to 16:9 for anime checking //closest to given ratio now, anime checking usually cant be done with depth search anyways since not every scene is screen capped online
}
private EmbedBuilder tempSearchSauce(String url) throws IOException {
EmbedBuilder eb = new EmbedBuilder();
eb.setColor(new Color(29, 29, 29));
try { //search iqdb first for the tags; results usually more organized and formatted
Element iqdb = Jsoup.connect("https://iqdb.org/?url=" + url + "&service[]=1&service[]=2&service[]=3&service[]=4&service[]=5&service[]=11&service[]=13").get().body(); //services excluding eshuushuu since it has no tags and will fallback to saucenao anyways
if(iqdb.select(".err").size() > 0 && iqdb.select(".err").html().contains("HTTP")) throw new IOException(iqdb.selectFirst(".err").ownText().split("\\.")[0]);
Elements tb = iqdb.select("th:contains(Best match)").get(0).parent().siblingElements();
Element img = tb.get(0).selectFirst("img");
eb.setThumbnail("https://iqdb.org/" + img.attr("src"));
eb.setTitle("Source: " + tb.get(1).selectFirst("td").ownText(), (img.parent().attr("href").contains("http") ? "" : "https:") + img.parent().attr("href"));
String tags = img.attr("alt").split("Tags:")[1];
eb.setDescription(tags.contains(",") ? tags.replaceAll(",", "\n") : tags.replaceAll(" ", "\n").replaceAll("\\_", " "));
eb.setFooter(tb.get(2).select("td").eachText().get(0) + " | " + tb.get(3).select("td").text(), null);
} catch (IndexOutOfBoundsException | SocketTimeoutException e) { //fallback to saucenao, usually pixiv source instead of image boards
try {
Element saucenao = Jsoup.connect("https://saucenao.com/search.php?url=" + url).get().body();
Element result = saucenao.selectFirst(".resulttable");
if(result == null) return null;
if(result.parent().attr("class").equals("result hidden")) return null;
eb.setThumbnail((result.selectFirst("img").attr("src").contains("http") ? "" : "https:") + result.selectFirst("img").attr("src").replaceAll(" ", "%20"));
try { //normal pixiv/deviantart handling
Element source = result.selectFirst("strong:contains(ID:)").nextElementSibling();
eb.setAuthor(result.select(".resulttitle strong").text());
eb.setTitle("Source: " + source.previousElementSibling().text().replaceAll("ID:", "#") + source.text(), source.attr("href"));
Element member = result.select(".linkify").get(2);
eb.setDescription("Author: [" + member.text() + "](" + member.attr("href") + ")");
} catch (NullPointerException e1) { //weird saucenao card formatting (eg episode info)
result.select("br").after("\\n");
String[] title = result.selectFirst(".resulttitle") == null ? new String[]{"No title"} : result.selectFirst(".resulttitle").wholeText().replaceAll("\\\\n", "\n").split("\n", 2); //there can be no titles, like 4chan sources
eb.setTitle(title[0], result.selectFirst(".resultmiscinfo a") == null ? null : result.selectFirst(".resultmiscinfo a").attr("href"));
if(title.length > 1) eb.appendDescription(title[1] + "\n");
eb.appendDescription(result.selectFirst(".resultcontentcolumn").wholeText().replaceAll("\\\\n", "\n"));
}
eb.setFooter(result.select(".resultsimilarityinfo").text() + " Similarity", null);
} catch (IndexOutOfBoundsException e1) {
return null;
}
}
return eb;
}
}
diff --git a/src/me/despawningbone/discordbot/command/anime/Waifu.java b/src/me/despawningbone/discordbot/command/anime/Waifu.java
index 9a4c79f..61366cd 100644
--- a/src/me/despawningbone/discordbot/command/anime/Waifu.java
+++ b/src/me/despawningbone/discordbot/command/anime/Waifu.java
@@ -1,190 +1,190 @@
package me.despawningbone.discordbot.command.anime;
import java.awt.Color;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.jsoup.Connection.Response;
import org.jsoup.Jsoup;
import me.despawningbone.discordbot.command.Command;
import me.despawningbone.discordbot.command.CommandResult;
import me.despawningbone.discordbot.command.CommandResult.CommandResultType;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.User;
public class Waifu extends Command {
public Waifu() {
this.desc = "Find information about your waifu!"; //, or leave it blank for a random one!";
this.usage = "<name> [| index]";
this.examples = Arrays.asList("neptune", "ryuZU");
}
@Override
public CommandResult execute(TextChannel channel, User author, Message msg, String[] args) {
channel.sendTyping().queue();
String[] stripped = String.join(" ", args).split("\\|");
/* , url = "";
if (args.length < 1) {
url = "https://mywaifulist.moe/random/";
} else {
url = "https://mywaifulist.moe/waifu/" + stripped.replaceAll(" ", "-");
}
JSONObject main = getWaifuJSON(url);
if (main == null) {
String search;
int index;
if (stripped.contains("|")) {
String[] split = stripped.split(" \\|");
search = split[0];
try {
index = Integer.parseInt(split[1].trim()) - 1;
} catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
channel.sendMessage("Invalid index inputted. Defaulting to first result.").queue();
channel.sendTyping().queue();
index = 0;
}
} else {
search = stripped;
index = 0;
}
try {
url = GoogleSearch
.search(URLEncoder.encode("site:https://mywaifulist.moe/waifu " + search, "UTF-8"), 20)
.get(index).getValue();
// System.out.println(url); //debug
} catch (IOException | IndexOutOfBoundsException e) {
if (e instanceof IndexOutOfBoundsException) {
return new CommandResult(CommandResultType.NORESULT);
} else {
return new CommandResult(CommandResultType.ERROR, ExceptionUtils.getStackTrace(e));
}
}
main = getWaifuJSON(url);
}*/
if(args.length < 1) return new CommandResult(CommandResultType.FAILURE, "Please enter something to search for!");
JSONObject main;
try {
Response con = Jsoup.connect("https://mywaifulist.moe/dash/").execute();
String cookie = String.join(";", con.header("Set-Cookie").split("; expires.*?,.*?,")).split("; expires")[0];
String csrf = con.parse().selectFirst("meta[name=\"csrf-token\"]").attr("content");
String res = Jsoup.connect("https://mywaifulist.moe/api/waifu/search")
.userAgent("Mozilla/4.0")
.header("Cookie", cookie)
.header("X-CSRF-Token", csrf)
.header("X-Requested-With", "XMLHttpRequest")
.followRedirects(true)
.requestBody("{\"query\":\"" + stripped[0].trim() + "\"}").post().text();
int index = 0;
JSONArray jarr = new JSONArray(new JSONTokener(res));
try {
//System.out.println(arr.length());
if(stripped.length > 1) index = Integer.parseInt(stripped[1].trim()) - 1;
if(jarr.length() <= index && index != 0) throw new NumberFormatException();
} catch (NumberFormatException e) {
channel.sendMessage("Invalid index inputted. Defaulting to first result.").queue();
channel.sendTyping().queue();
index = 0;
}
List<JSONObject> arr = new ArrayList<>();
for(Object obj : jarr) arr.add((JSONObject) obj);
arr = arr.stream().filter(o -> !o.getString("type").equalsIgnoreCase("series")).sorted((a, b) -> Integer.compare((b.has("likes") ? b.getInt("likes") : 0) + (b.has("trash") ? b.getInt("trash") : 0), (a.has("likes") ? a.getInt("likes") : 0) + (a.has("trash") ? a.getInt("trash") : 0))).collect(Collectors.toList()); //sort by popularity since the search result sucks ass
main = new JSONObject(new JSONTokener(Jsoup.connect("https://mywaifulist.moe/api/waifu/" + arr.get(index).getInt("id"))
.userAgent("Mozilla/4.0")
.header("Cookie", cookie)
.header("X-CSRF-Token", csrf)
.header("X-Requested-With", "XMLHttpRequest")
.followRedirects(true).ignoreContentType(true).get().text())).getJSONObject("data");
System.out.println(main);
} catch (IndexOutOfBoundsException e) {
//e.printStackTrace();
return new CommandResult(CommandResultType.NORESULT);
} catch (IOException e) {
return new CommandResult(CommandResultType.ERROR, ExceptionUtils.getStackTrace(e));
}
EmbedBuilder em = new EmbedBuilder();
em.setColor(new Color(44, 62, 80));
em.setTitle((main.getBoolean("husbando") ? "Husbando" : "Waifu") + " info of " + main.getString("name"), "https://mywaifulist.moe/waifu/" + main.getString("slug"));
JSONObject series = main.getJSONObject("series");
em.setAuthor("Series: " + series.getString("name"), "https://mywaifulist.moe/series/" + series.getString("slug"));
if(!main.getJSONObject("series").getString("display_picture").isEmpty()) em.setThumbnail(main.getJSONObject("series").getString("display_picture"));
try {
em.setDescription(main.getString("description").substring(0, Math.min(main.getString("description").length(), 2040)) + (main.getString("description").length() > 2040 ? "..." : ""));
} catch (IllegalArgumentException e) {
return new CommandResult(CommandResultType.TOOLONG);
}
em.setImage(main.getString("display_picture").replaceAll("\\\\", ""));
ArrayList<JSONObject> appearances = new ArrayList<>();
int totalName = 0;
for(Object obj : main.getJSONArray("appearances")) {
JSONObject jobj = ((JSONObject) obj);
appearances.add(jobj);
totalName += jobj.getString("name").length() + jobj.getString("slug").length() + 43;
}
final int avg = (1024 - totalName) / appearances.size();
System.out.println(appearances.stream().map(jobj -> "[" + jobj.getString("name") + "](https://mywaifulist.moe/series/" + jobj.getString("slug") + " \"" + jobj.getString("description").substring(0, Math.min(jobj.getString("description").length(), avg)) + (jobj.getString("description").length() > avg ? "..." : "").replaceAll("\"", "”") + "\")").collect(Collectors.joining(", ")).length());
em.addField("Appearances", appearances.stream().map(jobj -> "[" + jobj.getString("name") + "](https://mywaifulist.moe/series/" + jobj.getString("slug") + " \"" + jobj.getString("description").substring(0, Math.min(jobj.getString("description").length(), avg)) + (jobj.getString("description").length() > avg ? "..." : "").replaceAll("\"", "”") + "\")").collect(Collectors.joining(", ")), false);
if(!main.getString("original_name").isEmpty()) em.addField("Also known as", main.getString("original_name") + (main.isNull("romaji_name") ? "" : ", " + main.getString("romaji_name")), false);
em.addBlankField(false);
if (!main.getString("origin").equals("")) {
em.addField("Origin", main.getString("origin"), true);
}
if (main.getDouble("height") != 0.00) {
em.addField("Height", String.valueOf(main.getDouble("height")), true);
}
if (main.getDouble("weight") != 0.00) {
em.addField("Weight", String.valueOf(main.getDouble("weight")), true);
}
if (main.getDouble("bust") != 0.00) {
em.addField("Bust", String.valueOf(main.getDouble("bust")), true);
}
if (main.getDouble("hip") != 0.00) {
em.addField("Hip", String.valueOf(main.getDouble("hip")), true);
}
if (main.getDouble("waist") != 0.00) {
em.addField("Waist", String.valueOf(main.getDouble("waist")), true);
}
if (!main.getString("blood_type").isEmpty()) {
em.addField("Blood type", main.getString("blood_type"), true);
}
if (!main.isNull("birthday_day") && !main.getString("birthday_month").isEmpty()) {
em.addField("Birthday",
main.getString("birthday_month") + " " + String.valueOf(main.getInt("birthday_day"))
+ ( main.isNull("birthday_year") || main.getString("birthday_year").isEmpty() ? "" : ", " + main.getString("birthday_year")),
true);
}
if (em.getFields().size() == 5) {
em.addBlankField(true);
}
String tags = main.getJSONArray("tags").toList().stream().map(o -> o.toString().replaceAll("\\{name=", "").replaceAll(", id=.*\\}", "")).collect(Collectors.joining(", "));
if(!tags.isEmpty()) em.addField("Tags", tags, false);
if(em.getFields().size() > 2) em.addBlankField(false);
- em.addField("Likes", main.getInt("likes") + " (#" + main.getInt("like_rank") + ")", true);
- em.addField("Popularity rank", "#" + main.getInt("popularity_rank"), true);
- em.addField("Trash", main.getInt("trash") + " (#" + main.getInt("trash_rank") + ")", true);
+ em.addField("Likes", main.getInt("likes") + " (#" + (main.isNull("like_rank") ? "N/A" : main.getInt("like_rank")) + ")", true);
+ em.addField("Popularity rank", "#" + (main.isNull("popularity_rank") ? "N/A" : main.getInt("popularity_rank")), true);
+ em.addField("Trash", main.getInt("trash") + " (#" + (main.isNull("trash_rank") ? "N/A" : main.getInt("trash_rank")) + ")", true);
em.setFooter("Created by " + main.getJSONObject("creator").getString("name") + /*", Last updated: "
+ main.getString("updated_at") +*/ " | MyWaifuList.moe", null);
channel.sendMessage(em.build()).queue();
return new CommandResult(CommandResultType.SUCCESS);
}
}
diff --git a/src/me/despawningbone/discordbot/command/info/Calculator.java b/src/me/despawningbone/discordbot/command/info/Calculator.java
index 1ab2247..e685355 100644
--- a/src/me/despawningbone/discordbot/command/info/Calculator.java
+++ b/src/me/despawningbone/discordbot/command/info/Calculator.java
@@ -1,227 +1,230 @@
package me.despawningbone.discordbot.command.info;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
-import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EmptyStackException;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import javax.imageio.ImageIO;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.math3.special.Gamma;
import org.json.JSONObject;
import org.json.JSONTokener;
import com.neovisionaries.ws.client.WebSocket;
import com.neovisionaries.ws.client.WebSocketAdapter;
import com.neovisionaries.ws.client.WebSocketException;
import com.neovisionaries.ws.client.WebSocketFactory;
import me.despawningbone.discordbot.command.Command;
import me.despawningbone.discordbot.command.CommandResult;
import me.despawningbone.discordbot.command.CommandResult.CommandResultType;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.TextChannel;
import net.dv8tion.jda.api.entities.User;
import net.objecthunter.exp4j.Expression;
import net.objecthunter.exp4j.ExpressionBuilder;
import net.objecthunter.exp4j.function.Function;
import net.objecthunter.exp4j.operator.Operator;
public class Calculator extends Command {
public Calculator() {
this.alias = Arrays.asList("calc");
this.desc = "Do some calculations!";
this.usage = "[-w] <operation>";
this.remarks = Arrays.asList("This calculator is using exp4j.",
"You can get the built in operators and functions at:", "http://projects.congrace.de/exp4j/",
"`!` - factorials", "`logx(base, num)` - logarithm (base x)", "are supported too.",
"\nYou can also query [Wolfram Alpha](https://www.wolframalpha.com/) using the `-w` switch.");
this.examples = Arrays.asList("3*4-2", "4 * (sin(3 - 5)) + 5!", "log(e) + logx(10, 100)", " -w laurent series log(x) about x=0");
}
- Function logb = new Function("logx", 2) {
+ static final double planckConstant = 6.62607004 * Math.pow(10, -34), eulerMascheroni = 0.57721566490153286060651209008240243104215933593992;
+
+ static final Function logb = new Function("logx", 2) {
@Override
public double apply(double... args) {
return Math.log(args[1]) / Math.log(args[0]);
}
};
- Function digamma = new Function("digamma", 1) {
+ static final Function digamma = new Function("digamma", 1) {
@Override
public double apply(double... args) {
return Gamma.digamma(args[0]);
}
};
- Operator factorial = new Operator("!", 2, true, Operator.PRECEDENCE_POWER + 1) {
+ static final Operator factorial = new Operator("!", 2, true, Operator.PRECEDENCE_POWER + 1) {
@Override
public double apply(double... args) {
final long arg = (long) args[0];
if ((double) arg != args[0]) {
throw new IllegalArgumentException("Operand for factorial has to be an integer");
}
if (arg < 0) {
throw new IllegalArgumentException("The operand of the factorial can not " + "be " + "less than zero");
}
double result = 1;
for (int i = 1; i <= arg; i++) {
result *= i;
}
return result;
}
};
@Override
public CommandResult execute(TextChannel channel, User author, Message msg, String[] args) {
List<String> params = new ArrayList<>(Arrays.asList(args));
if(params.removeAll(Collections.singleton("-w"))) {
return queryWolfram(String.join(" ", params), channel);
} else {
if (args.length < 1) {
return new CommandResult(CommandResultType.INVALIDARGS, "Please enter an operation.");
}
- String splitted = String.join(" ", args);
+ String splitted = String.join(" ", args);
+
+ //easter eggs
if (msg.getContentDisplay().toLowerCase().contains("the meaning of life, the universe, and everything")) { // easter egg
channel.sendMessage("The answer is: `42`").queue();
return new CommandResult(CommandResultType.SUCCESS, "Executed easter egg");
}
if (splitted.equals("9+10") || splitted.equals("9 + 10")) { // easter egg
channel.sendMessage("The answer is: `21`\n\n *i am smart ;)*").queue();
return new CommandResult(CommandResultType.SUCCESS, "Executed easter egg");
}
if (splitted.equals("666") || splitted.equals("333")) { // easter egg
channel.sendMessage("No you don't").queue();
return new CommandResult(CommandResultType.SUCCESS, "Executed easter egg");
- } else {
- String operation = String.join("", args);
- if (operation.contains("!")) {
- int index = operation.indexOf("!");
- while (index >= 0) { // indexOf returns -1 if no match found
- operation = new StringBuilder(operation).insert(index + 1, "(1)").toString();
- index = operation.indexOf("!", index + 1);
- }
- }
- DecimalFormat format = new DecimalFormat();
- format.setDecimalSeparatorAlwaysShown(false);
- // System.out.println(operation);
- Expression e = null;
- String ans = null;
- double planckConstant = 6.62607004 * Math.pow(10, -34);
- double eulerMascheroni = 0.57721566490153286060651209008240243104215933593992;
- try {
- e = new ExpressionBuilder(operation).variable("h").variable("γ").function(digamma).function(logb).operator(factorial).build()
- .setVariable("h", planckConstant).setVariable("γ", eulerMascheroni);
- ans = Double.toString(e.evaluate());
- // String ans = format.format(e.evaluate());
- } catch (EmptyStackException e1) {
- return new CommandResult(CommandResultType.INVALIDARGS, "You have imbalanced parentheses.");
- } catch (ArithmeticException e1) {
- return new CommandResult(CommandResultType.INVALIDARGS, "You cannot divide by zero.");
- } catch (IllegalArgumentException e1) {
- return new CommandResult(CommandResultType.FAILURE, "An error has occured: " + e1.getMessage());
- }
- if (ans.equals("NaN")) {
- ans = "Undefined";
+ }
+
+ //patch for factorial formatting
+ String operation = String.join("", args);
+ if (operation.contains("!")) {
+ int index = operation.indexOf("!");
+ while (index >= 0) { // indexOf returns -1 if no match found
+ operation = new StringBuilder(operation).insert(index + 1, "(1)").toString();
+ index = operation.indexOf("!", index + 1);
}
- channel.sendMessage("The answer is: `" + ans + "`").queue();
- return new CommandResult(CommandResultType.SUCCESS);
- }
+ }
+
+ // DecimalFormat format = new DecimalFormat();
+ // format.setDecimalSeparatorAlwaysShown(false);
+ // System.out.println(operation);
+ String ans = null;
+ try {
+ Expression e = new ExpressionBuilder(operation).variable("h").variable("γ").function(digamma).function(logb).operator(factorial).build()
+ .setVariable("h", planckConstant).setVariable("γ", eulerMascheroni);
+ ans = Double.toString(e.evaluate());
+ // String ans = format.format(e.evaluate());
+ } catch (EmptyStackException e1) {
+ return new CommandResult(CommandResultType.INVALIDARGS, "You have imbalanced parentheses.");
+ } catch (ArithmeticException e1) {
+ return new CommandResult(CommandResultType.INVALIDARGS, "You cannot divide by zero.");
+ } catch (IllegalArgumentException e1) {
+ return new CommandResult(CommandResultType.FAILURE, "An error has occured: " + e1.getMessage());
+ }
+ if (ans.equals("NaN")) {
+ ans = "Undefined";
+ }
+ channel.sendMessage("The answer is: `" + ans + "`").queue();
+ return new CommandResult(CommandResultType.SUCCESS);
+
}
}
public CommandResult queryWolfram(String operation, TextChannel channel) {
channel.sendTyping().queue();
try {
CompletableFuture<CommandResult> result = new CompletableFuture<>();
WebSocket socket = new WebSocketFactory().createSocket("wss://www.wolframalpha.com/n/v1/api/fetcher/results");
ArrayList<Integer> pos = new ArrayList<>(); //prevent duplicate
socket.addListener(new WebSocketAdapter() {
@Override
public void onTextMessage(WebSocket websocket, String message) {
try {
//System.out.println(message);
JSONObject resp = new JSONObject(new JSONTokener(message));
switch(resp.getString("type")) {
case "pods":
for(Object obj : resp.getJSONArray("pods")) { //pods might have multiple values
JSONObject pod = (JSONObject) obj;
if(pod.getBoolean("error")) continue; //skip errors
if(!pos.contains(pod.getInt("position"))) { //check dupe
//build big image for each pods
ArrayList<BufferedImage> images = new ArrayList<>();
int width = 0, height = 0;
if(!pod.has("subpods")) continue; //ignore empty pods that doesnt have image, usually fixed somewhere else
for(Object subobj : pod.getJSONArray("subpods")) {
JSONObject subpodImg = ((JSONObject) subobj).getJSONObject("img");
images.add(ImageIO.read(new URL(subpodImg.getString("src"))));
if(subpodImg.getInt("width") > width) width = subpodImg.getInt("width"); //get widest image and use it as final width
height += subpodImg.getInt("height"); //add all images
}
//create final image
BufferedImage podImg = new BufferedImage(width + 20, height + 20, BufferedImage.TYPE_INT_RGB); //padding
Graphics g = podImg.getGraphics();
g.setColor(new Color(255, 255, 255)); //fill as white first
g.fillRect(0, 0, width + 20, height + 20);
int y = 10;
for(BufferedImage img : images) {
g.drawImage(img, 10, y, null);
y += img.getHeight();
}
//send each pod as an individual message
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(podImg, "png", os);
channel.sendMessage(pod.getString("title") + ":")
.addFile(new ByteArrayInputStream(os.toByteArray()), "result.png").queue();
pos.add(pod.getInt("position")); //update to prevent dupes
}
}
break;
case "futureTopic":
result.complete(new CommandResult(CommandResultType.FAILURE, "This query was identified under the topic of `" + resp.getJSONObject("futureTopic").getString("topic") + "`; Development of this topic is under investigation..."));
break;
case "didyoumean":
result.complete(new CommandResult(CommandResultType.INVALIDARGS, "No good results found :cry:\nDid you mean `" + resp.getJSONArray("didyoumean").getJSONObject(0).getString("val") + "`?"));
break;
case "noResult":
result.complete(new CommandResult(CommandResultType.NORESULT));
break;
case "queryComplete": //might provide no output for certain queries, but theres no practical way to detect with this listener rn
websocket.disconnect();
result.complete(new CommandResult(CommandResultType.SUCCESS)); //if its preceded by anything it wouldnt update; thats how complete() works
break;
}
} catch(Exception e) {
result.complete(new CommandResult(CommandResultType.ERROR, ExceptionUtils.getStackTrace(e)));
}
}
});
//System.out.println("{\"type\":\"init\",\"lang\":\"en\",\"exp\":" + System.currentTimeMillis() + ",\"displayDebuggingInfo\":false,\"messages\":[{\"type\":\"newQuery\",\"locationId\":\"hipuj\",\"language\":\"en\",\"displayDebuggingInfo\":false,\"yellowIsError\":false,\"input\":\"" + operation + "\",\"assumption\":[],\"file\":null}],\"input\":\"" + operation + "\",\"assumption\":[],\"file\":null}");
socket.connect();
socket.sendText("{\"type\":\"init\",\"lang\":\"en\",\"exp\":" + System.currentTimeMillis() + ",\"displayDebuggingInfo\":false,\"messages\":[{\"type\":\"newQuery\",\"locationId\":\"hipuj\",\"language\":\"en\",\"displayDebuggingInfo\":false,\"yellowIsError\":false,\"input\":\"" + operation + "\",\"assumption\":[],\"file\":null}],\"input\":\"" + operation + "\",\"assumption\":[],\"file\":null}");
return result.get();
} catch (IOException | WebSocketException | InterruptedException | ExecutionException e) {
return new CommandResult(CommandResultType.ERROR, ExceptionUtils.getStackTrace(e));
}
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jun 17, 7:43 AM (1 d, 8 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
c6/44/78737af6205094680ec4d6c35c5e

Event Timeline