package readers; import java.awt.Color; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.regex.Pattern; import javax.imageio.ImageIO; import readers.fonts.Font; import readers.fonts.Glyph; public class DDRReader extends Reader{ final static int REGION_PADDING = 32; List<Box> extraRegions = new ArrayList<>(); static int lastJump=0; boolean failed=false; public DDRReader(){ addRegion(new Box(305,428,402,69),NUMBER); //score[0]+ addRegion(new Box(603,565,133,37),NUMBER); //max combo[1]+ addRegion(new Box(603,612,133,37),NUMBER); //marvelous[2]+ addRegion(new Box(603,651,133,37),NUMBER); //perfect[3]+ addRegion(new Box(603,698,133,37),NUMBER); //great[4]+ addRegion(new Box(603,742,133,37),NUMBER); //good[5]+ addRegion(new Box(603,787,133,37),NUMBER); //OK[6]+ addRegion(new Box(603,830,133,37),NUMBER); //miss[7]+ addRegion(new Box(603,876,133,37),NUMBER); //ex score[8]+ addRegion(new Box(783,738,133,37),NUMBER); //fast[9]+ addRegion(new Box(783,821,133,37),NUMBER); //slow[10]+ addRegion(new Box(600,165,133,53),NUMBER); //diffnumb[11]+ addRegion(new Box(577,91,174,36)); //playstyle[12] addRegion(new Box(253,207,357,183)); //grade[13] addRegion(new Box(756,432,411,38)); //songname[14] addRegion(new Box(576,126,185,40)); //difficulty text[15] init(); } void ColorFilter(int[] arr,int region,int width) { switch (region) { case 0:{ process(arr,width, 247,255,247,255,247,255, 200,255,200,255,200,255); }break; case 1:{ process(arr,width, 180,255,180,255,180,255, 70,255,70,255,70,255); }break; case 2:{ process(arr,width, 0,50,0,50,0,50, 0,160,0,160,0,160); }break; case 3:{ process(arr,width, 0,50,0,50,0,50, 0,160,0,160,0,160); }break; case 4:{ process(arr,width, 0,50,0,50,0,50, 0,160,0,160,0,160); }break; case 5:{ process(arr,width, 0,50,0,50,0,50, 0,160,0,160,0,160); }break; case 6:{ process(arr,width, 0,50,0,50,0,50, 0,160,0,160,0,160); }break; case 7:{ process(arr,width, 0,50,0,50,0,50, 0,160,0,160,0,160); }break; case 8:{ process(arr,width, 190,255,190,255,190,255, 140,255,140,255,140,255); }break; case 9:{ process(arr,width, 0,50,0,50,0,50, 0,160,0,160,0,160); }break; case 10:{ process(arr,width, 0,50,0,50,0,50, 0,160,0,160,0,160); }break; case 11:{ process(arr,width, 190,255,190,255,190,255, 140,255,140,255,140,255); }break; case 12:{ process(arr,width, 190,255,190,255,190,255, 140,255,140,255,140,255); }break; } } public void interpretBoxes(Path img,boolean testingMode){ /*String dataString = readAllBoxes(img); String[] data = dataString.split(Pattern.quote("\n")); String[] ja_data = data[0].split(Pattern.quote(")")); String[] en_data = data[2].split(Pattern.quote(")")); trimAllData(ja_data); trimAllData(en_data); System.out.println(Arrays.toString(ja_data)); System.out.println(Arrays.toString(en_data));*/ int regionHeights = 0; int maxWidth = 0; int counter=0; for (int i=0;i<readRegions.size();i++) { regionHeights+=readRegions.get(i).h+REGION_PADDING; if (readRegions.get(i).w>maxWidth) { maxWidth=readRegions.get(i).w*2; } } try { BufferedImage originalImg = ImageIO.read(img.toFile()); BufferedImage cutImg = new BufferedImage(maxWidth,regionHeights,BufferedImage.TYPE_INT_ARGB); Graphics2D g = cutImg.createGraphics(); int currentHeight=0; for (int i=0;i<readRegions.size();i++) { BufferedImage subRegion = new BufferedImage(readRegions.get(i).w, readRegions.get(i).h,BufferedImage.TYPE_INT_ARGB); subRegion.setRGB(0,0,readRegions.get(i).w,readRegions.get(i).h,originalImg.getRGB(readRegions.get(i).x, readRegions.get(i).y, readRegions.get(i).w, readRegions.get(i).h, null, 0, readRegions.get(i).w),0,readRegions.get(i).w); int[] arr = subRegion.getRGB(0, 0, readRegions.get(i).w, readRegions.get(i).h, null, 0, readRegions.get(i).w); //System.out.println(Arrays.toString(arr)); //System.out.println(i); //ImageIO.write(originalImg.getSubimage(readRegions.get(i).x, readRegions.get(i).y, readRegions.get(i).w, readRegions.get(i).h),"png",new File("cut.png")); ColorFilter(arr,i,readRegions.get(i).w); subRegion.setRGB(0,0,readRegions.get(i).w,readRegions.get(i).h,arr,0,readRegions.get(i).w); ImageIO.write(subRegion,"png",new File("sub.png")); cutImg.setRGB(0,currentHeight,readRegions.get(i).w,readRegions.get(i).h,arr,0,readRegions.get(i).w); String val = interpretImage(subRegion,i); sig_data[counter++]=val; if (i==0) { //Blank out the scores because it has commas iwn it. arr = new int[readRegions.get(i).w*readRegions.get(i).h]; cutImg.setRGB(0,currentHeight,readRegions.get(i).w,readRegions.get(i).h,arr,0,readRegions.get(i).w); } if (i==13) { Color col = new Color(subRegion.getRGB(131,84),true); ColorRange range = new ColorRange(130,135,130,135,130,135); if (range.colorInRange(col)) { failed=true; } } currentHeight+=readRegions.get(i).h+REGION_PADDING; } Path output = Paths.get("result.png"); ImageIO.write(cutImg,"png",output.toFile()); if (testingMode) { interpretOutput(new String[]{},new String[]{},sig_data); } else { String dataString = readAllBoxes(output); String[] data = dataString.split(Pattern.quote("\n")); String[] ja_data = parseOutCommas(data[0]).split(Pattern.quote(",")); String[] en_data = parseOutCommas(data[2]).split(Pattern.quote(",")); trimAllData(ja_data); trimAllData(en_data); System.out.println(Arrays.toString(ja_data)); System.out.println(Arrays.toString(en_data)); System.out.println(Arrays.toString(sig_data)); interpretOutput(ja_data,en_data,sig_data); } g.dispose(); } catch (IOException e) { e.printStackTrace(); } //System.out.println(data[0]); //System.out.println(data[2]); } private String interpretImage(BufferedImage cutImg, int i) { switch (i) { case 0:{ Font f = Font.FONT_DDR_SCORE; List<Glyph> glyphs = Glyph.split(cutImg); if (glyphs.size()==9) { //This is a 1,000,000 score. glyphs.remove(5); glyphs.remove(1); } else if (glyphs.size()>4) { //This is a XXX,XXX score. glyphs.remove(3); } return f.convertGlyphs(glyphs); } case 1: case 8:{ Font f = Font.FONT_DDR_EXCOMBO; List<Glyph> glyphs = Glyph.split(cutImg); return f.convertGlyphs(glyphs); } case 2: case 3: case 4: case 5: case 6: case 7: case 9: case 10:{ Font f = Font.FONT_DDR_NOTECOUNT; List<Glyph> glyphs = Glyph.split(cutImg); return f.convertGlyphs(glyphs); } case 11:{ Font f = Font.FONT_DDR_DIFF; List<Glyph> glyphs = Glyph.split(cutImg); return f.convertGlyphs(glyphs); } } return ""; } String interpretResults(String[] finalData) { for (int i=0;i<finalData.length;i++) { String[] splitter = finalData[i].split(Pattern.quote("\n")); switch (i) { case 0:{ score=convertToInt(splitter); }break; case 1:{ maxcombo=convertToInt(splitter); }break; case 2:{ notes[0]=convertToInt(splitter); }break; case 3:{ notes[1]=convertToInt(splitter); }break; case 4:{ notes[2]=convertToInt(splitter); }break; case 5:{ notes[3]=convertToInt(splitter); }break; case 6:{ notes[4]=convertToInt(splitter); }break; case 7:{ notes[5]=convertToInt(splitter); }break; case 8:{ other="{\"ex\":"+convertToInt(splitter); }break; case 9:{ other=other+",\"fast\":"+convertToInt(splitter); }break; case 10:{ other=other+",\"slow\":"+convertToInt(splitter); }break; case 11:{ difficulty=convertToInt(splitter); }break; case 12:{ other=other+",\"playstyle\":\""+convertToString(splitter)+"\""; }break; case 13:{ if (failed) { rank=15;/*F*/ } else if (score>=990000) {rank=0;/*AAA*/} else if (score>=950000) {rank=1;/*AA+*/} else if (score>=910000) {rank=2;/*AA*/} else if (score>=900000) {rank=3;/*AA-*/} else if (score>=850000) {rank=4;/*A+*/} else if (score>=810000) {rank=5;/*A*/} else if (score>=800000) {rank=6;/*A-*/} else if (score>=750000) {rank=7;/*B+*/} else if (score>=710000) {rank=8;/*B*/} else if (score>=700000) {rank=9;/*B-*/} else if (score>=650000) {rank=10;/*C+*/} else if (score>=610000) {rank=11;/*C*/} else if (score>=600000) {rank=12;/*C-*/} else if (score>=550000) {rank=13;/*D+*/} else {rank=14;/*D*/} }break; case 14:{ title=convertToString(splitter); }break; case 15:{ other=other+",\"diff\":\""+convertToString(splitter)+"\"}"; }break; } } return toString(); } }