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