package Modules; import Controll.GuildController; import Controll.SuperModule; import net.dv8tion.jda.api.EmbedBuilder; import net.dv8tion.jda.api.entities.Message; import net.dv8tion.jda.api.events.GenericEvent; import net.dv8tion.jda.api.events.message.guild.GuildMessageReceivedEvent; import org.joda.time.DateTime; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.io.*; import java.net.URL; import java.nio.file.Files; import java.nio.file.Paths; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Fold extends SuperModule{ private final Logger logger = LoggerFactory.getLogger(Fold.class); public static final String COMMAND = "fold"; private static final int BYTE_LIMIT = 16 * 1024; private static final int MAX_MESSAGE_LIMIT = 10; private static final String teamSummary = "https://apps.foldingathome.org/daily_team_summary.txt", userSummary = "https://apps.foldingathome.org/daily_user_summary.txt"; private String teamFile = "/home/bots/MissingIdentifier/MissingIdent/team_summary.txt", userFile = "/home/bots/MissingIdentifier/MissingIdent/user_summary.txt"; public Fold(GuildController guildController){ super(COMMAND, guildController, null); } @Override public String getCommand() { return Fold.COMMAND; } @Override public String getDescription() { return "Get statistics for a team that partakes in https://foldingathome.org\n`fold -t TEAMNAME` teamname to be filtered\n`fold -u update` update statistics"; } @Override public void execute(GenericEvent genericEvent) { if (!(genericEvent instanceof GuildMessageReceivedEvent)) return; GuildMessageReceivedEvent event = (GuildMessageReceivedEvent) genericEvent; if (!isCommand(event.getMessage())) return; logger.debug("Fold command triggered"); //VARS Pattern teamPattern, userPattern; Message msg = event.getChannel().sendMessage("Got it!").complete(); String teamInfo = null; // Update Locale Files if parameter "u" is given if (getParameter(event.getMessage().getContentRaw(), "u") != null) msg = update(event, msg); // Generate Pattern to look for decide if looking for ID or Name of Team fall back is null and will cause an error if (getParameter(event.getMessage().getContentRaw(), "t") != null) { String input = getParameter(event.getMessage().getContentRaw(), "t"); logger.info("looking for team: " + input); teamPattern = Pattern.compile("(?m)^[0-9]+\\t" + input + "\\t[0-9]+\\t[0-9]+$"); } else if (getParameter(event.getMessage().getContentRaw(), "id") != null) { String input = getParameter(event.getMessage().getContentRaw(), "id"); logger.info("looking for team: " + input); teamPattern = Pattern.compile("(?m)^" + input + "\\t[^\\t]*\\t[0-9]+\\t[0-9]+$"); } else return; // TODO error handling //LOOK for Team try (BufferedReader teamReader = Files.newBufferedReader(Paths.get(teamFile))) { teamInfo = teamReader.readLine(); while (teamInfo != null) { Matcher teamMatcher = teamPattern.matcher(teamInfo); if (teamMatcher.find()) { // Send quick info msg = msg.editMessage(teamMatcher.group()).complete(); break; } teamInfo = teamReader.readLine(); } } catch (IOException e) { logger.error(e.toString()); } if (teamInfo == null) { msg.editMessage("No team with this Identifier found!").queue(); return; } // Look for users try (BufferedReader userReader = Files.newBufferedReader(Paths.get(userFile))) { // Like skringbuilder only for embeded messages EmbedBuilder eb = new EmbedBuilder(); // Add Team info eb.setTitle(teamInfo.split("\t")[1] + " [ " + teamInfo.split("\t")[0] + " ]"); // Team Name eb.setDescription("Work Units done:\t" + teamInfo.split("\t")[3] + "\n" + "Total Score:\t\t" + teamInfo.split("\t")[2]); // WUs and Score eb.setTimestamp(new DateTime().toDate().toInstant()); userPattern = Pattern.compile("(?m)^[0-9a-zA-Z_]+\\t[0-9]+\\t[0-9]+\\t" + teamInfo.split("\t")[0] + "$"); String userInfo = userReader.readLine(); long userPosition = 0; int messageCount = 0; msg = msg.editMessage(teamInfo + "\n\nread 0 lines").complete(); while (userInfo != null) { userPosition++; Matcher userMatcher = userPattern.matcher(userInfo); if (userMatcher.find()) { eb.addField(userInfo.split("\t")[0], "Work Units:\t" + userInfo.split("\t")[2] + "\n" + "Score:\t\t" + userInfo.split("\t")[1], true); //msg = msg.editMessage(teamInfo + "\n\nread " + userPosition + " lines").complete(); // IF mesage is to long, rmeove last entry and split output if (!eb.isValidLength()){ eb.getFields().remove(eb.getFields().size()-1); msg.getChannel().sendMessage(eb.build()).complete(); eb = new EmbedBuilder(); messageCount++; if(messageCount > MAX_MESSAGE_LIMIT){ msg.getChannel().sendMessage("To many entries! aborted to prevent spam!").queue(); return; } eb.addField(userInfo.split("\t")[0], "Work Units:\t" + userInfo.split("\t")[2] + "\n" + "Score:\t\t" + userInfo.split("\t")[1], true); } } if (userPosition % 250000 == 0) msg = msg.editMessage(teamInfo + "\n\nread " + userPosition + " lines").complete(); userInfo = userReader.readLine(); } //Send final result msg.getChannel().sendMessage(eb.build()).complete(); msg.delete().queue(); } catch (IOException e) { logger.error(e.toString()); } } private Message update(GuildMessageReceivedEvent event, Message msg) { if(!checkForAdmin(event.getMember())) { // if the user that calls this function is not admin, here should be an interval check that interrupts if the files have recently been updated to mitigate abuse. // admins should of course be able to call this any time. // the date of the current files can be read from the first line of each file and needs to be parsed. return msg; // if it's not done by an admin, just cancel out } logger.debug("Get new Statistic from Server"); TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted( java.security.cert.X509Certificate[] certs, String authType) { } public void checkServerTrusted( java.security.cert.X509Certificate[] certs, String authType) { } } }; // Activate the new trust manager try { SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); } catch (Exception e) { logger.error(e.toString()); } byte buffer[] = new byte[BYTE_LIMIT]; int bytesRead; try( BufferedOutputStream teamOutput = new BufferedOutputStream(new FileOutputStream(teamFile, false)); BufferedInputStream teamInput = new BufferedInputStream(new URL(teamSummary).openStream()) ) { long i = 0; while((bytesRead = teamInput.read(buffer, 0, BYTE_LIMIT)) != -1){ teamOutput.write(buffer, 0, bytesRead); i+=bytesRead; if (i % 50000 <= 200) msg = msg.editMessage("Updating Teamstats, processed " + i + " Bytes").complete(); } teamOutput.flush(); } catch (IOException e) { logger.error(e.toString()); } try( BufferedOutputStream userOutput = new BufferedOutputStream(new FileOutputStream(userFile, false)); BufferedInputStream userInput = new BufferedInputStream(new URL(userSummary).openStream()) ){ long i = 0; while((bytesRead = userInput.read(buffer, 0, BYTE_LIMIT)) != -1){ userOutput.write(buffer, 0, bytesRead); i+=bytesRead; if (i % 50000 <= 200) msg = msg.editMessage("Updating Userstats, processed " + i + " Bytes").complete(); } userOutput.flush(); } catch (IOException e) { logger.error(e.toString()); } return msg.editMessage("done!").complete(); } @Override public String showSettings() { return null; } }