diff --git a/BandoriBot/.classpath b/BandoriBot/.classpath index 1f094c3..758ba95 100644 --- a/BandoriBot/.classpath +++ b/BandoriBot/.classpath @@ -3,5 +3,6 @@ + diff --git a/BandoriBot/BandoriBot.jar b/BandoriBot/BandoriBot.jar index 88935e8..e93f164 100644 Binary files a/BandoriBot/BandoriBot.jar and b/BandoriBot/BandoriBot.jar differ diff --git a/BandoriBot/JDA-3.8.0_423-withDependencies.jar b/BandoriBot/JDA-3.8.0_423-withDependencies.jar new file mode 100644 index 0000000..8e09e32 Binary files /dev/null and b/BandoriBot/JDA-3.8.0_423-withDependencies.jar differ diff --git a/BandoriBot/commons-io-2.5.jar b/BandoriBot/commons-io-2.5.jar new file mode 100644 index 0000000..1234918 Binary files /dev/null and b/BandoriBot/commons-io-2.5.jar differ diff --git a/BandoriBot/newstar.png b/BandoriBot/newstar.png new file mode 100644 index 0000000..f0a6963 Binary files /dev/null and b/BandoriBot/newstar.png differ diff --git a/BandoriBot/projectbuilder.xml b/BandoriBot/projectbuilder.xml index 813a75c..f436979 100644 --- a/BandoriBot/projectbuilder.xml +++ b/BandoriBot/projectbuilder.xml @@ -13,7 +13,8 @@ - + + \ No newline at end of file diff --git a/BandoriBot/src/sig/BandoriBot.java b/BandoriBot/src/sig/BandoriBot.java index 55631b6..bc4db34 100644 --- a/BandoriBot/src/sig/BandoriBot.java +++ b/BandoriBot/src/sig/BandoriBot.java @@ -34,6 +34,7 @@ public class BandoriBot extends ListenerAdapter{ public static JDA bot; public static int messageCounter = 0; Random r = new Random(); + static GachaBot gacha; public static String[] eventsList = new String[]{ "Making Choco Cornets", @@ -166,6 +167,7 @@ public class BandoriBot extends ListenerAdapter{ } catch (LoginException | InterruptedException e) { e.printStackTrace(); } + gacha = new GachaBot(bot); File store_file = new File(BASEDIR+"bot_status.txt"); if (store_file.exists()) { try { @@ -183,6 +185,7 @@ public class BandoriBot extends ListenerAdapter{ } while (true) { noMessageTimer++; + GachaBot.tick(); if (noMessageTimer>7200) { if (noMessageTimer>18000) { currentEvent = "Dreaming about stars"; @@ -240,7 +243,7 @@ public class BandoriBot extends ListenerAdapter{ } } try { - System.out.println("Current Event: "+currentEvent+"; Timer: "+currentEventTimer+"; No Message Timer: "+noMessageTimer+"; Message Counter: "+messageCounter); + //System.out.println("Current Event: "+currentEvent+"; Timer: "+currentEventTimer+"; No Message Timer: "+noMessageTimer+"; Message Counter: "+messageCounter); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); @@ -396,7 +399,7 @@ public class BandoriBot extends ListenerAdapter{ System.out.println("Channel "+channel+": "+user+" - "+message); - if (user.getUser().getId().equalsIgnoreCase("494666451765035009")) { + if (user.getUser().getIdLong()==494666451765035009l) { return; } @@ -416,9 +419,11 @@ public class BandoriBot extends ListenerAdapter{ return; } - if (channel.getId().equalsIgnoreCase("485297375665979414")) { + if (channel.getId().equalsIgnoreCase("485297375665979414") || + channel.getId().equalsIgnoreCase("509845287284768801")) { System.out.println("Detected in Bandori Channel...."); checkForStamp(messaging_channel,user.getEffectiveName(),message); + gacha.checkForGacha(messaging_channel,user.getEffectiveName(),user.getUser().getIdLong(),message); } diff --git a/BandoriBot/src/sig/DrawUtils.java b/BandoriBot/src/sig/DrawUtils.java new file mode 100644 index 0000000..3559771 --- /dev/null +++ b/BandoriBot/src/sig/DrawUtils.java @@ -0,0 +1,129 @@ +package sig; + +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.TextAttribute; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.awt.image.ImageObserver; +import java.text.AttributedString; + +public class DrawUtils { + public static void drawOutlineText(Graphics g, Font font, double x, double y, int outline_size, Color text_color, Color shadow_color, String message) { + drawOutlineText(g,font,x,y,0,0,1,outline_size,text_color,shadow_color,message); + } + public static void drawOutlineText(Graphics g, Font font, double x, double y, int font_thickness, int outline_thickness, Color text_color, Color shadow_color, String message) { + drawOutlineText(g,font,x,y,0,0,font_thickness,outline_thickness,text_color,shadow_color,message); + } + static void drawOutlineText(Graphics g, Font font, double x, double y, double xoffset, double yoffset, int font_thickness, int outline_thickness, Color text_color, Color shadow_color, String message) { + AttributedString as = new AttributedString(message); + as.addAttribute(TextAttribute.FONT, font); + g.setColor(shadow_color); + Graphics2D g2 = (Graphics2D) g; + FontRenderContext frc = g2.getFontMetrics(font).getFontRenderContext(); + GlyphVector gv = font.createGlyphVector(frc, message); + Shape shape = gv.getOutline((int)(x+xoffset),(int)(y+yoffset)); + g2.setClip(null); + g2.setStroke(new BasicStroke(font_thickness + outline_thickness*2)); + g2.setColor(shadow_color); + g2.setRenderingHint( + RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g2.draw(shape); + GlyphVector gv2 = font.createGlyphVector(frc, message); + Shape shape2 = gv2.getOutline((int)(x+xoffset),(int)(y+yoffset)); + g2.setClip(null); + g2.setStroke(new BasicStroke(font_thickness)); + g2.setColor(text_color); + g2.setRenderingHint( + RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g2.draw(shape2); + g2.setColor(text_color); + g2.drawString(as.getIterator(),(int)(x+xoffset),(int)(y+yoffset)); + } + public static void drawCenteredOutlineText(Graphics g, Font font, double x, double y, int outline_size, Color text_color, Color shadow_color, String message) { + Rectangle2D textBounds = TextUtils.calculateStringBoundsFont(g,message, font); + drawOutlineText(g,font,x,y,-textBounds.getWidth()/2,-textBounds.getHeight()/2,1,outline_size,text_color,shadow_color,message); + } + public static void drawTextFont(Graphics g, Font font, double x, double y, Color color, String message) { + if (message.length()>0) { + AttributedString as = new AttributedString(message); + as.addAttribute(TextAttribute.FONT, font); + g.setColor(color); + g.drawString(as.getIterator(),(int)x,(int)y); + } + } + public static void drawHealthbar(Graphics g, Rectangle bounds, double pct, Color healthbarcol) { + g.setColor(Color.BLACK); + g.draw3DRect((int)bounds.getX(), (int)bounds.getY(), (int)bounds.getWidth(), (int)bounds.getHeight(), true); + g.setColor(healthbarcol); + g.fill3DRect((int)bounds.getX()+1, (int)bounds.getY()+1, (int)(bounds.getWidth()*pct)-1, (int)bounds.getHeight()-1, true); + } + /** + * Centers the text along the X Axis. + */ + public static void drawCenteredText(Graphics g, Font font, int x, int y, Color color, String text) { + AttributedString as = new AttributedString(text); + as.addAttribute(TextAttribute.FONT, font); + g.setColor(color); + Rectangle2D textBounds = TextUtils.calculateStringBoundsFont(g,text, font); + g.drawString(as.getIterator(),(int)(x-textBounds.getWidth()/2),(int)(y+textBounds.getHeight())); + } + + public static Color convertStringToColor(String s) { + String[] split = s.split(","); + if (split.length==3) { + return new Color( + Math.min(Math.abs(Integer.parseInt(split[0])),255), + Math.min(Math.abs(Integer.parseInt(split[1])),255), + Math.min(Math.abs(Integer.parseInt(split[2])),255)); + } else + if (split.length==4) { + return new Color( + Math.min(Math.abs(Integer.parseInt(split[0])),255), + Math.min(Math.abs(Integer.parseInt(split[1])),255), + Math.min(Math.abs(Integer.parseInt(split[2])),255), + Math.min(Math.abs(Integer.parseInt(split[3])),255)); + } else { + System.out.println("WARNING! Invalid Color string specified ("+s+")."); + return null; + } + } + + public static void drawImage(Graphics g, Image img, double x, double y, Color blend_col, ImageObserver source) { + BufferedImage tmp = new BufferedImage(img.getWidth(source),img.getHeight(source),BufferedImage.TYPE_INT_ARGB); + Graphics2D g2 = tmp.createGraphics(); + g2.drawImage(img, 0, 0, null); + g2.setComposite(AlphaComposite.SrcAtop); + g2.setColor(blend_col); + g2.fillRect(0, 0, img.getWidth(source), img.getHeight(source)); + g2.dispose(); + g.drawImage(tmp,(int)x,(int)y,source); + } + + public static void drawImageScaled(Graphics g, Image img, double x, double y, double xsize, double ysize, Color blend_col, ImageObserver source) { + BufferedImage tmp = new BufferedImage(img.getWidth(source),img.getHeight(source),BufferedImage.TYPE_INT_ARGB); + Graphics2D g2 = tmp.createGraphics(); + g2.drawImage(img, 0, 0, null); + g2.setComposite(AlphaComposite.SrcAtop); + g2.setColor(blend_col); + g2.fillRect(0, 0, img.getWidth(source), img.getHeight(source)); + g2.dispose(); + g.drawImage(tmp,(int)x,(int)y,(int)xsize,(int)ysize,source); + } + + public static Color invertColor(Color c) { + return new Color(255-c.getRed(),255-c.getGreen(),255-c.getBlue(),255); + } +} diff --git a/BandoriBot/src/sig/FileUtils.java b/BandoriBot/src/sig/FileUtils.java index b705d3e..483a23a 100644 --- a/BandoriBot/src/sig/FileUtils.java +++ b/BandoriBot/src/sig/FileUtils.java @@ -11,8 +11,11 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.PrintWriter; import java.io.Reader; +import java.net.HttpURLConnection; import java.net.URL; +import java.nio.channels.Channels; import java.nio.channels.FileChannel; +import java.nio.channels.ReadableByteChannel; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.HashMap; @@ -153,6 +156,7 @@ public class FileUtils { //System.out.println(sb.toString()); return sb.toString(); } + public static JSONObject readJsonFromUrlWithFilter(String url, HashMap filter) throws IOException, JSONException { return readJsonFromUrlWithFilter(url,filter,null,false); @@ -206,35 +210,78 @@ public class FileUtils { is.close(); } } + public static JSONObject readJsonFromFile(File file) throws IOException, JSONException { + InputStream is = new FileInputStream(file); + try { + BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); + String jsonText = readAll(rd); + JSONObject json = new JSONObject(jsonText); + jsonText=null; + return json; + } finally { + is.close(); + } + } public static JSONObject readJsonFromUrl(String url, String file, boolean writeToFile) throws IOException, JSONException { - InputStream is = new URL(url).openStream(); - try { - BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); - String jsonText = readAll(rd); - if (writeToFile) { - writetoFile(new String[]{jsonText},file); - } - JSONObject json = new JSONObject(jsonText); - return json; - } finally { - is.close(); - } + //InputStream is = new URL(url).openStream(); + URL site = new URL(url); + HttpURLConnection connection = (HttpURLConnection) site.openConnection(); + /*for (String s : connection.getHeaderFields().keySet()) { + System.out.println(s+": "+connection.getHeaderFields().get(s)); + }*/ + //connection.setRequestMethod("GET"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("User-Agent", "Mozilla/5.0"); + int response = connection.getResponseCode(); + //System.out.println("Response: "+response); + InputStreamReader stream = new InputStreamReader(connection.getInputStream()); + BufferedReader rd = new BufferedReader(stream); + String jsonText = readAll(rd); + if (writeToFile) { + writetoFile(new String[]{jsonText},file); + } + JSONObject json = new JSONObject(jsonText); + stream.close(); + return json; + } + + public static void downloadFileFromUrl(String url, String file) throws IOException, JSONException { + URL website = new URL(url); + HttpURLConnection connection = (HttpURLConnection) website.openConnection(); + /*for (String s : connection.getHeaderFields().keySet()) { + System.out.println(s+": "+connection.getHeaderFields().get(s)); + }*/ + //connection.setRequestMethod("GET"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("User-Agent", "Mozilla/5.0"); + ReadableByteChannel rbc = Channels.newChannel(connection.getInputStream()); + FileOutputStream fos = new FileOutputStream(file); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); } public static JSONArray readJsonArrayFromUrl(String url, String file, boolean writeToFile) throws IOException, JSONException { - InputStream is = new URL(url).openStream(); - try { - BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); - String jsonText = readAll(rd); - if (writeToFile) { - writetoFile(new String[]{jsonText},file); - } - JSONArray json = new JSONArray(jsonText); - return json; - } finally { - is.close(); - } + //InputStream is = new URL(url).openStream(); + URL site = new URL(url); + HttpURLConnection connection = (HttpURLConnection) site.openConnection(); + /*for (String s : connection.getHeaderFields().keySet()) { + System.out.println(s+": "+connection.getHeaderFields().get(s)); + }*/ + //connection.setRequestMethod("GET"); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestProperty("User-Agent", "Mozilla/5.0"); + int response = connection.getResponseCode(); + //System.out.println("Response: "+response); + InputStreamReader stream = new InputStreamReader(connection.getInputStream()); + BufferedReader rd = new BufferedReader(stream); + String jsonText = readAll(rd); + if (writeToFile) { + writetoFile(new String[]{jsonText},file); + } + JSONArray json = new JSONArray(jsonText); + stream.close(); + return json; } public static void logToFile(String message, String filename) { diff --git a/BandoriBot/src/sig/GachaBot.java b/BandoriBot/src/sig/GachaBot.java new file mode 100644 index 0000000..fc74863 --- /dev/null +++ b/BandoriBot/src/sig/GachaBot.java @@ -0,0 +1,319 @@ +package sig; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.GraphicsEnvironment; +import java.awt.font.FontRenderContext; +import java.awt.geom.Rectangle2D; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.text.DecimalFormat; +import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.imageio.ImageIO; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import net.dv8tion.jda.core.JDA; +import net.dv8tion.jda.core.MessageBuilder; +import net.dv8tion.jda.core.entities.Message; +import net.dv8tion.jda.core.entities.MessageChannel; +import sig.gacha.Card; +import sig.gacha.Member; +import sig.gacha.Player; + +public class GachaBot { + JDA bot; + static int cardcount = 0; + static int membercount = 0; + public static int databasecheck = 86400; + public static List cardlist = new ArrayList(); + public static List memberlist = new ArrayList(); + public static Font programFont = new Font("Century Schoolbook L",Font.PLAIN,24); + public GachaBot(JDA bot) { + this.bot=bot; + UpdateCardDatabase(); + CreateFileDirectories(); + String fonts[] = + GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); + + for ( int i = 0; i < fonts.length; i++ ) + { + System.out.println(fonts[i]); + } + } + + private void CreateFileDirectories() { + new File(BandoriBot.BASEDIR+"art/").mkdirs(); + new File(BandoriBot.BASEDIR+"card_art/").mkdirs(); + new File(BandoriBot.BASEDIR+"gacha_results/").mkdirs(); + new File(BandoriBot.BASEDIR+"profiles/").mkdirs(); + } + + public static void tick() { + databasecheck--; + if (databasecheck==0) { + databasecheck=0; + UpdateCardDatabase(); + } + } + + public void checkForGacha(MessageChannel channel,String name,Long discordID,String message) { + System.out.println(message+" | "+message.charAt(0)); + if (message.length()>0 && message.charAt(0)=='.') { + //This is a bot message. Try to work with it. + String[] wordparse = message.split(" "); + System.out.println(Arrays.toString(wordparse)); + switch (wordparse[0]) { + case ".stats":{ + Player p = Player.GetPlayerProfile(discordID, name); + DecimalFormat df = new DecimalFormat("0.0"); + channel.sendMessage(new MessageBuilder("*Stats for* "+name+":").append('\n') + .append("```Total Rolls: "+(p.GetPullData()[0]+p.GetPullData()[1]+p.GetPullData()[2])).append('\n') + .append("4* Cards: "+(p.GetPullData()[2])+" ("+df.format((double)(p.GetPullData()[2])/(p.GetPullData()[0]+p.GetPullData()[1]+p.GetPullData()[2])*100)+"%)").append(" ["+p.GetDupeData()[2]+" dupe"+((p.GetDupeData()[2]==1)?"":"s")+"]").append('\n') + .append("3* Cards: "+(p.GetPullData()[1])+" ("+df.format((double)(p.GetPullData()[1])/(p.GetPullData()[0]+p.GetPullData()[1]+p.GetPullData()[2])*100)+"%)").append(" ["+p.GetDupeData()[1]+" dupe"+((p.GetDupeData()[1]==1)?"":"s")+"]").append('\n') + .append("2* Cards: "+(p.GetPullData()[0])+" ("+df.format((double)(p.GetPullData()[0])/(p.GetPullData()[0]+p.GetPullData()[1]+p.GetPullData()[2])*100)+"%)").append(" ["+p.GetDupeData()[0]+" dupe"+((p.GetDupeData()[0]==1)?"":"s")+"]").append('\n') + .append("```").build()).queue(); + }break; + case ".gacha":{ + //System.out.print("This is a gacha attempt~!"); + int amt = 1; + if (wordparse.length>1) { + try { + amt = Integer.parseInt(wordparse[1]); + } catch (NumberFormatException e) { + + } + if (amt!=5 && amt!=10) { + amt = 1; + } + } + int original_amt = amt; + BufferedImage img = new BufferedImage(180*((amt==5||amt==10)?5:1),180*((amt==10)?2:1),BufferedImage.TYPE_INT_ARGB); + Graphics2D g = img.createGraphics(); + int x_offset = 0; + int y_offset = 0; + List picked_cards = new ArrayList(); + Player p = Player.GetPlayerProfile(discordID,name); + do { + double rng = Math.random(); + int star_rating = 2; + if (rng<0.03) { + //4-star. + star_rating=4; + } else + if (rng<0.085){ + //3-star. + star_rating=3; + } else { + star_rating=2; + } + if (original_amt>1 && amt==1) { + if (rng<0.03) { + //4-star. + star_rating=4; + } else { + star_rating=3; + } + } + Card c = Card.pickRandomCardByStarRating(cardlist, star_rating); + boolean trained = (star_rating>2 && p.getNumberOfCardsInCollection(c)%2==1); + picked_cards.add(c); + System.out.println("Requesting Card "+c+" from "+c.getCardURL(trained)); + try { + FileUtils.downloadFileFromUrl(c.getCardURL(trained), "card_art/"+c.getCardID()+((trained)?"_trained":"")+".png"); + } catch (JSONException | IOException e) { + e.printStackTrace(); + } + File card_file = new File(BandoriBot.BASEDIR+"card_art/"+c.getCardID()+((trained)?"_trained":"")+".png"); + File star_file = new File(BandoriBot.BASEDIR+"newstar.png"); + //channel.sendFile(card_file).queue(); + BufferedImage card_img = null; + try { + card_img = ImageIO.read(card_file); + } catch (IOException e) { + e.printStackTrace(); + } + g.drawImage(card_img, x_offset, y_offset, null); + card_img.flush(); + if (!p.hasCardInCollection(c)) { + try { + card_img = ImageIO.read(star_file); + g.drawImage(card_img, x_offset+180-64, y_offset+180-64, null); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (p.getNumberOfCardsInCollection(c)>0) { + g.setFont(programFont); + FontRenderContext frc = g.getFontMetrics(programFont).getFontRenderContext(); + String displayString = Integer.toString(p.getNumberOfCardsInCollection(c)+1); + Rectangle2D size = programFont.getStringBounds(displayString, frc); + //g.drawString(displayString, (float)(x_offset+180-size.getX()-4), (float)(y_offset+180-size.getY()-4)); + DrawUtils.drawOutlineText(g, programFont, (float)(x_offset+180-size.getWidth()-12), (float)(y_offset+180-size.getHeight()+20), 1, 2, Color.BLACK, Color.WHITE, displayString); + } + x_offset+=180; + if (x_offset>=900) { + x_offset=0; + y_offset+=180; + } + card_img.flush(); + } while (--amt>0); + // + long systemTime = System.currentTimeMillis(); + File gacha_result = new File(BandoriBot.BASEDIR+"gacha_results/"+systemTime+".png"); + try { + ImageIO.write(img, "png", gacha_result); + } catch (IOException e) { + e.printStackTrace(); + } + Message msg = new MessageBuilder().append("*Gacha Result for "+name+"*").build(); + channel.sendFile(gacha_result,msg).queue(); + g.dispose(); + img.flush(); + + //Player p = Player.GetPlayerProfile(discordID,name); + Player.ApplyAllCardProfileChanges(bot,channel,name,discordID,message,picked_cards); + }break; + case ".display":{ + if (wordparse.length>1) { //This is a valid ID to try. + /*try { + int card_id = Integer.parseInt(wordparse[1]); + Card c = Card.findCardByID(cardlist, card_id); + if (c!=null) { + //Download the image... + try { + FileUtils.downloadFileFromUrl(c.getCardArtURL(false), "art/"+card_id+".png"); + channel.sendFile(new File(BandoriBot.BASEDIR+"art/"+card_id+".png")).queue(); + } catch (JSONException | IOException e) { + e.printStackTrace(); + } + } else { + channel.sendMessage("*I am sorry, but I cannot find that!!!*").queue(); + } + } + catch (NumberFormatException e) { + channel.sendMessage("*I am sorry, but I would like a number there instead...*").queue(); + }*/ + String character = wordparse[1]; + Member m = Member.getMemberByName(memberlist, character); + if (m!=null) { + int character_id = m.getMemberID(); + Card c = Card.pickRandomCardByMemberID(cardlist, character_id); + if (c!=null) { + //Download the image... + try { + int card_id = c.getCardID(); + boolean trained = false; + if (c.getCardStarRating()>2) { + trained = Math.random()<0.5; + } + System.out.println("Requesting Card "+c+" from "+c.getCardArtURL(trained)); + FileUtils.downloadFileFromUrl(c.getCardArtURL(trained), "art/"+card_id+((trained)?"_trained":"")+".png"); + channel.sendFile(new File(BandoriBot.BASEDIR+"art/"+card_id+((trained)?"_trained":"")+".png")).queue(); + } catch (JSONException | IOException e) { + e.printStackTrace(); + } + } else { + channel.sendMessage("*I am sorry, but something went wrong!*").queue(); + } + } else { + channel.sendMessage("*I am sorry, but I cannot find the person you are looking for! Check your spelling!* :xD:").queue(); + } + } + }break; + } + } + } + + private static void UpdateCardDatabase() { + int cardsLoaded = 0; + int membersLoaded = 0; + List tempcardlist = new ArrayList(); + List tempmemberlist = new ArrayList(); + try { + int pagecount = 1; + do { + JSONObject jsondata = FileUtils.readJsonFromUrl("https://bandori.party/api/cards/?page="+pagecount++); + //jsondata = FileUtils.readJsonFromFile(file); + cardcount = jsondata.getInt("count"); + String nexturl = ""; + String prevurl = ""; + if (jsondata.get("next") instanceof String) { + nexturl = (String)jsondata.get("next"); + } else { + nexturl = ""; + } + if (jsondata.get("previous") instanceof String) { + prevurl = (String)jsondata.get("previous"); + } else { + prevurl = ""; + } + JSONArray carddata = jsondata.getJSONArray("results"); + //System.out.println(cardcount+";"+nexturl+";"+prevurl+";"+carddata); + for (Object obj : carddata) { + JSONObject card = (JSONObject) obj; + tempcardlist.add(new Card(card)); + cardsLoaded++; + } + if (nexturl.length()==0) { + break; + } + } while (true); + System.out.println("Loaded "+cardsLoaded+" / "+cardcount+" cards."); + } catch (JSONException | IOException e) { + e.printStackTrace(); + } + try { + int pagecount = 1; + do { + JSONObject jsondata = FileUtils.readJsonFromUrl("https://bandori.party/api/members/?page="+pagecount++); + //jsondata = FileUtils.readJsonFromFile(file); + membercount = jsondata.getInt("count"); + String nexturl = ""; + String prevurl = ""; + if (jsondata.get("next") instanceof String) { + nexturl = (String)jsondata.get("next"); + } else { + nexturl = ""; + } + if (jsondata.get("previous") instanceof String) { + prevurl = (String)jsondata.get("previous"); + } else { + prevurl = ""; + } + JSONArray memberdata = jsondata.getJSONArray("results"); + //System.out.println(cardcount+";"+nexturl+";"+prevurl+";"+carddata); + for (Object obj : memberdata) { + JSONObject member = (JSONObject) obj; + tempmemberlist.add(new Member(member)); + membersLoaded++; + } + if (nexturl.length()==0) { + break; + } + } while (true); + System.out.println("Loaded "+membersLoaded+" / "+membercount+" characters."); + } catch (JSONException | IOException e) { + e.printStackTrace(); + } + if (cardsLoaded == cardcount) { + cardlist.clear(); + cardlist.addAll(tempcardlist); + System.out.println("Updated all card entries."); + } + if (membersLoaded == membercount) { + memberlist.clear(); + memberlist.addAll(tempmemberlist); + System.out.println("Updated all member entries."); + } + } +} diff --git a/BandoriBot/src/sig/TextUtils.java b/BandoriBot/src/sig/TextUtils.java new file mode 100644 index 0000000..7091512 --- /dev/null +++ b/BandoriBot/src/sig/TextUtils.java @@ -0,0 +1,135 @@ +package sig; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.font.FontRenderContext; +import java.awt.geom.Rectangle2D; +import java.util.ArrayList; +import java.util.List; + + +public class TextUtils { + + public static Rectangle2D calculateStringBoundsFont(Graphics g, String msg, Font font) { + FontRenderContext frc = g.getFontMetrics(font).getFontRenderContext(); + return font.getStringBounds(msg, frc); + } + + public static String replaceFirst(String sourcestring, String findstring, String replacestring) { + int pos = sourcestring.indexOf(findstring); + if (pos>=0) { + String piece1 = sourcestring.substring(0,pos); + String piece2 = sourcestring.substring(pos+findstring.length(),sourcestring.length()); + //basemsg = basemsg.replaceFirst(e.getEmoteName(),e.getSpaceFiller()); + sourcestring = piece1+replacestring+piece2; + } + return sourcestring; + } + + public static boolean isAlphanumeric(String str) { + return str.matches("^[a-zA-Z0-9!\\-.?'\":,\\+ ]+$"); + } + + public static boolean isNumeric(String str) + { + if (str.length()>0) { + return str.matches("-?\\d+(\\.\\d+)?"); //match a number with optional '-' and decimal. + } else { + return false; + } + } + + public static boolean isInteger(String s, int radix) { + if(s.isEmpty()) return false; + for(int i = 0; i < s.length(); i++) { + if(i == 0 && s.charAt(i) == '-') { + if(s.length() == 1) return false; + else continue; + } + if(Character.digit(s.charAt(i),radix) < 0) return false; + } + return true; + } + + public static String convertSecondsToTimeFormat(int seconds) { + StringBuilder sb = new StringBuilder(); + int sec = seconds%60; + int min = (seconds/60)%60; + int hrs = (seconds/3600)%24; + if (hrs>0) { + if (hrs>=10) { + sb.append(hrs); + } else { + sb.append(0); + sb.append(hrs); + } + sb.append(":"); + } + if (min>=10) { + sb.append(min); + } else { + sb.append(0); + sb.append(min); + } + sb.append(":"); + if (sec>=10) { + sb.append(sec); + } else { + sb.append(0); + sb.append(sec); + } + return sb.toString(); + } + + /** + * Converts a three CSV value to RGB value. + */ + public static Color convertStringToColor(String col) { + String[] split = col.split(","); + return new Color(Integer.parseInt(split[0]),Integer.parseInt(split[1]),Integer.parseInt(split[2])); + } + + public static List WrapText(Graphics g,String msg, Font font, double width) { + List displayMessage = new ArrayList(); + String rawmessage = msg; + int textWidth = (int)TextUtils.calculateStringBoundsFont(g,rawmessage, font).getWidth(); + int maxWidth = (int)width; + do { + rawmessage = BreakTextAtNextSection(g,rawmessage+" ",font,displayMessage,maxWidth); + textWidth = (int)TextUtils.calculateStringBoundsFont(g,rawmessage, font).getWidth(); + } while (textWidth>maxWidth); + if (rawmessage.length()>0) { + displayMessage.add(rawmessage); + } + return displayMessage; + //System.out.println(displayMessage+": "+messageDisplaySize); + } + + private static String BreakTextAtNextSection(Graphics g, String msg, Font font, List list, int maxWidth) { + int marker = 1; + int textWidth = (int)TextUtils.calculateStringBoundsFont(g,msg.substring(0, marker), font).getWidth(); + while (textWidth database,int cardID) { + for (Card c : database) { + if (c.id == cardID) { + return c; + } + } + return null; + } + + public static Card pickRandomCardByStarRating(List database,int stars) { + List cardList = new ArrayList(); + for (Card c : database) { + if (c.rarity==stars) { + cardList.add(c); + } + } + return cardList.get((int)(Math.random()*cardList.size())); + } + + public static Card pickRandomCardByMemberID(List database,int memberID) { + List cardList = new ArrayList(); + for (Card c : database) { + if (c.member == memberID) { + cardList.add(c); + } + } + return cardList.get((int)(Math.random()*cardList.size())); + } + + public String getCardURL(boolean trained) { + if (trained) { + return imgURL_trained; + } else { + return imgURL; + } + } + + public String getCardArtURL(boolean trained) { + if (trained) { + return artURL_trained; + } else { + return artURL; + } + } + + public int getCardID() { + return id; + } + + public int getCardStarRating() { + return rarity; + } + + int getIntFromJson(JSONObject data, String key) { + if (data.has(key) && data.get(key) instanceof Integer) { + return data.getInt(key); + } + return -1; + } + String getStringFromJson(JSONObject data, String key) { + if (data.has(key) && data.get(key) instanceof String) { + return data.getString(key); + } + return ""; + } + JSONArray getJSONArrayFromJson(JSONObject data, String key) { + if (data.has(key) && data.get(key) instanceof JSONArray) { + return data.getJSONArray(key); + } + JSONArray empty = new JSONArray(); + return empty; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(this.getClass().getName()+"("); + boolean first=false; + for (Field f : this.getClass().getDeclaredFields()) { + if (!first) { + try { + sb.append(f.getName()+"="+f.get(this)); + first=true; + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } else { + try { + sb.append(","+f.getName()+"="+f.get(this)); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + } + sb.append(")"); + return sb.toString(); + } +} diff --git a/BandoriBot/src/sig/gacha/Member.java b/BandoriBot/src/sig/gacha/Member.java new file mode 100644 index 0000000..a982070 --- /dev/null +++ b/BandoriBot/src/sig/gacha/Member.java @@ -0,0 +1,78 @@ +package sig.gacha; + +import java.util.List; + +import org.json.JSONObject; + +public class Member { + int id; + String name; + String jap_name; + String imageURL; + String square_imageURL; + String band; + String school; + String school_year; + String va; + String jap_va; + String birthday; + String food_likes; + String food_dislikes; + String horoscope; + String hobbies; + String desc; + + public Member(JSONObject data) { + id = getIntFromJson(data,"id"); + name = getStringFromJson(data,"name"); + jap_name = getStringFromJson(data,"japanese_name"); + imageURL = getStringFromJson(data,"image"); + square_imageURL = getStringFromJson(data,"square_image"); + band = getStringFromJson(data,"i_band"); + school = getStringFromJson(data,"school"); + school_year = getStringFromJson(data,"i_school_year"); + va = getStringFromJson(data,"romaji_CV"); + jap_va = getStringFromJson(data,"CV"); + birthday = getStringFromJson(data,"birthday"); + food_likes = getStringFromJson(data,"food_likes"); + food_dislikes = getStringFromJson(data,"food_dislikes"); + horoscope = getStringFromJson(data,"i_astrological_sign"); + hobbies = getStringFromJson(data,"hobbies"); + desc = getStringFromJson(data,"description"); + } + + public static Member getMemberByName(List database, String name) { + for (Member m : database) { + if (m.name.split(" ")[0].equalsIgnoreCase(name)) { + return m; + } + } + return null; + } + + public static Member getMemberByID(List database, int id) { + for (Member m : database) { + if (m.id==id) { + return m; + } + } + return null; + } + + public int getMemberID() { + return id; + } + + int getIntFromJson(JSONObject data, String key) { + if (data.has(key) && data.get(key) instanceof Integer) { + return data.getInt(key); + } + return -1; + } + String getStringFromJson(JSONObject data, String key) { + if (data.has(key) && data.get(key) instanceof String) { + return data.getString(key); + } + return ""; + } +} diff --git a/BandoriBot/src/sig/gacha/Player.java b/BandoriBot/src/sig/gacha/Player.java new file mode 100644 index 0000000..2c083cb --- /dev/null +++ b/BandoriBot/src/sig/gacha/Player.java @@ -0,0 +1,220 @@ +package sig.gacha; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +import org.json.JSONException; + +import net.dv8tion.jda.core.JDA; +import net.dv8tion.jda.core.MessageBuilder; +import net.dv8tion.jda.core.entities.Message; +import net.dv8tion.jda.core.entities.MessageChannel; +import sig.BandoriBot; +import sig.FileUtils; +import sig.GachaBot; + +public class Player { + long discordID; + String discordName; + int pulls4; + int pulls3; + int pulls2; + int dupepulls4; + int dupepulls3; + int dupepulls2; + HashMap card_collection = new HashMap(); + + public Player(long discordID, String discordName) { + this.discordID = discordID; + this.discordName = discordName; + pulls4=0; + pulls3=0; + pulls2=0; + dupepulls4=0; + dupepulls3=0; + dupepulls2=0; + //SavePlayerProfile(); + } + + public void SavePlayerProfile() { + String[] format = GetFileData(); + FileUtils.writetoFile(format, BandoriBot.BASEDIR+"profiles/"+discordID); + } + + public int[] GetPullData() { + return new int[]{pulls2,pulls3,pulls4}; + } + + public int[] GetDupeData() { + return new int[]{dupepulls2,dupepulls3,dupepulls4}; + } + + private String[] GetFileData() { + List fileFormat = new ArrayList(); + fileFormat.add(Long.toString(discordID)); + fileFormat.add(discordName); + fileFormat.add(Integer.toString(pulls4)); + fileFormat.add(Integer.toString(pulls3)); + fileFormat.add(Integer.toString(pulls2)); + for (Integer card_id : card_collection.keySet()) { + Integer amt = card_collection.get(card_id); + fileFormat.add(card_id+";"+amt); + } + return fileFormat.toArray(new String[fileFormat.size()]); + } + + public boolean hasCardInCollection(Card c) { + return card_collection.containsKey(c.id); + } + + public int getNumberOfCardsInCollection(Card c) { + if (card_collection.containsKey(c.id)) { + return card_collection.get(c.id); + } else { + return 0; + } + } + + public void addCardToCollection(Card c) { + switch (c.rarity) { + case 3:{ + pulls3++; + }break; + case 4:{ + pulls4++; + }break; + default:{ + pulls2++; + } + } + if (card_collection.containsKey(c.id)) { + card_collection.put(c.id,card_collection.get(c.id)+1); + switch (c.rarity) { + case 3:{ + dupepulls3++; + }break; + case 4:{ + dupepulls4++; + }break; + default:{ + dupepulls2++; + } + } + } else { + card_collection.put(c.id, 1); + } + } + + public static Player GetPlayerProfile(Long discordID,String discordName) { + File f = new File(BandoriBot.BASEDIR+"profiles/"+discordID); + if (f.exists()) { + return GetPlayerProfile(discordID); + } else { + return new Player(discordID,discordName); + } + } + + private static Player GetPlayerProfile(long discordID) { + String[] filedata = FileUtils.readFromFile(BandoriBot.BASEDIR+"profiles/"+discordID); + int i = 0; + long tempid = Long.parseLong(filedata[i++]); + String myname = filedata[i++]; + Player p = new Player(tempid,myname); + p.pulls4 = Integer.parseInt(filedata[i++]); + p.pulls3 = Integer.parseInt(filedata[i++]); + p.pulls2 = Integer.parseInt(filedata[i++]); + while (i1) { + switch (c.rarity) { + case 3:{ + p.dupepulls3+=cardcount-1; + }break; + case 4:{ + p.dupepulls4+=cardcount-1; + }break; + default:{ + p.dupepulls2+=cardcount-1; + } + } + } + System.out.println("Loaded card "+c.id+" to profile "+p.discordName); + } + return p; + } + + public static void ApplyAllCardProfileChanges(JDA bot, MessageChannel channel, String name, Long discordID, + String message, List cards) { + Player p = Player.GetPlayerProfile(discordID,name); + for (Card c : cards) { + p.addCardToCollection(c); + PerformRewards(bot,channel,p,c); + } + p.SavePlayerProfile(); + } + + private static void PerformRewards(JDA bot, MessageChannel channel, Player p, Card c) { + int card_amt = p.card_collection.get(c.id); + if (c.rarity==4 && card_amt>=1 && + card_amt<3) { + //Download the image... + try { + int card_id = c.getCardID(); + boolean trained = (card_amt==2)?true:false; + System.out.println("Requesting Card "+c+" from "+c.getCardArtURL(trained)); + FileUtils.downloadFileFromUrl(c.getCardArtURL(trained), "art/"+card_id+((trained)?"_trained":"")+".png"); + Message msg; + if (card_amt==1) { + msg = new MessageBuilder().append("*Congratulations for unlocking a new* 4\\* **"+p.discordName+"**!").append('\n'). + append("**"+Member.getMemberByID(GachaBot.memberlist, c.member).name+"** ["+c.name+"]").build(); + } else { + msg = new MessageBuilder().append("**"+p.discordName+"** unlocked the trained version of **"+Member.getMemberByID(GachaBot.memberlist, c.member).name+"** ["+c.name+"]! **Congratulations!**").build(); + } + channel.sendFile(new File(BandoriBot.BASEDIR+"art/"+card_id+((trained)?"_trained":"")+".png"),msg).queue(); + } catch (JSONException | IOException e) { + e.printStackTrace(); + } + } else + if (c.rarity==3 && card_amt>=5 && + card_amt<11) { + //Download the image... + try { + int card_id = c.getCardID(); + boolean trained = (card_amt==10)?true:false; + System.out.println("Requesting Card "+c+" from "+c.getCardArtURL(trained)); + FileUtils.downloadFileFromUrl(c.getCardArtURL(trained), "art/"+card_id+((trained)?"_trained":"")+".png"); + Message msg; + if (card_amt==5) { + msg = new MessageBuilder().append("**Congratulations for collecting 5 **"+Member.getMemberByID(GachaBot.memberlist, c.member).name+"** ["+c.name+"] **"+p.discordName+"**!").build(); + } else { + msg = new MessageBuilder().append("**Congratulations for collecting 10 **"+Member.getMemberByID(GachaBot.memberlist, c.member).name+"** ["+c.name+"] **"+p.discordName+"**!").build(); + } + channel.sendFile(new File(BandoriBot.BASEDIR+"art/"+card_id+((trained)?"_trained":"")+".png"),msg).queue(); + } catch (JSONException | IOException e) { + e.printStackTrace(); + } + } else + if (c.rarity==2 && card_amt==100) { + //Download the image... + try { + int card_id = c.getCardID(); + boolean trained = false; + System.out.println("Requesting Card "+c+" from "+c.getCardArtURL(trained)); + FileUtils.downloadFileFromUrl(c.getCardArtURL(trained), "art/"+card_id+((trained)?"_trained":"")+".png"); + Message msg; + msg = new MessageBuilder().append("**Congratulations for collecting 100 **"+Member.getMemberByID(GachaBot.memberlist, c.member).name+"** ["+c.name+"] **"+p.discordName+"**!").build(); + channel.sendFile(new File(BandoriBot.BASEDIR+"art/"+card_id+((trained)?"_trained":"")+".png"),msg).queue(); + } catch (JSONException | IOException e) { + e.printStackTrace(); + } + } + } +} diff --git a/BandoriBot/stamps/aya_miracles.png b/BandoriBot/stamps/aya_miracles.png new file mode 100644 index 0000000..6a8e322 Binary files /dev/null and b/BandoriBot/stamps/aya_miracles.png differ diff --git a/BandoriBot/stamps/aya_pressure.png b/BandoriBot/stamps/aya_pressure.png new file mode 100644 index 0000000..dabf992 Binary files /dev/null and b/BandoriBot/stamps/aya_pressure.png differ diff --git a/BandoriBot/stamps/chisato_thisissomuchfun.png b/BandoriBot/stamps/chisato_thisissomuchfun.png index e76bfb3..197c2f0 100644 Binary files a/BandoriBot/stamps/chisato_thisissomuchfun.png and b/BandoriBot/stamps/chisato_thisissomuchfun.png differ diff --git a/BandoriBot/stamps/eve_bushido.png b/BandoriBot/stamps/eve_bushido.png index 010720a..67283ab 100644 Binary files a/BandoriBot/stamps/eve_bushido.png and b/BandoriBot/stamps/eve_bushido.png differ diff --git a/BandoriBot/stamps/hagumi_hooray.png b/BandoriBot/stamps/hagumi_hooray.png new file mode 100644 index 0000000..b1b42dd Binary files /dev/null and b/BandoriBot/stamps/hagumi_hooray.png differ diff --git a/BandoriBot/stamps/kanon_keepgoing.png b/BandoriBot/stamps/kanon_keepgoing.png new file mode 100644 index 0000000..b5eff4b Binary files /dev/null and b/BandoriBot/stamps/kanon_keepgoing.png differ diff --git a/BandoriBot/stamps/kokoro_what_a_great_idea.png b/BandoriBot/stamps/kokoro_what_a_great_idea.png new file mode 100644 index 0000000..97cabbb Binary files /dev/null and b/BandoriBot/stamps/kokoro_what_a_great_idea.png differ diff --git a/BandoriBot/stamps/rinko_theresnoway.png b/BandoriBot/stamps/rinko_theresnoway.png index 5280d15..82a10a4 100644 Binary files a/BandoriBot/stamps/rinko_theresnoway.png and b/BandoriBot/stamps/rinko_theresnoway.png differ diff --git a/BandoriBot/stamps/saya_illtry.png b/BandoriBot/stamps/saya_illtry.png index e61c03e..f96ce50 100644 Binary files a/BandoriBot/stamps/saya_illtry.png and b/BandoriBot/stamps/saya_illtry.png differ diff --git a/BandoriBot/stamps/sayo_im_sorry.png b/BandoriBot/stamps/sayo_im_sorry.png new file mode 100644 index 0000000..b864e27 Binary files /dev/null and b/BandoriBot/stamps/sayo_im_sorry.png differ diff --git a/BandoriBot/stamps/tsugumi_amazing.png b/BandoriBot/stamps/tsugumi_amazing.png new file mode 100644 index 0000000..712d0cb Binary files /dev/null and b/BandoriBot/stamps/tsugumi_amazing.png differ