import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.regex.Pattern; import javax.imageio.ImageIO; import readers.ColorRange; import readers.DDRReader; import readers.ITGReader; import readers.LoveLiveReader; import readers.PopnReader; import readers.Reader; import readers.SoundVoltexReader; import readers.TestReader; import java.awt.image.BufferedImage; import java.io.IOException; import java.awt.Color; public class ArcadeReader { /* * Important data we would like to know for all games: * Score * Rank (Probably implementation-specific) * Note accuracy [List] * Marvelous * Perfect * Great * Good * Bad * OK * Miss * Difficulty * Song Name / Title * Percentage (Can be EX Score, a percentage accuracy or survival percent) * Max Combo * Other (Not used by the auto detecter, used for storing misc. data.) * * Notes about Readers: * Love Live * - Does not use: Marvelous, OK * Project Diva * - Does not use: Marvelous, OK * - Fail condition is MISSxTAKE * DDR * - Does not use: Max Combo (Cannot calculate in combo carryover mode), Bad * - Fail condition is E rank. * Pop'n Music * - Does not use: Marvelous, Bad, OK * - Stores number of bars filled in Percentage. * - Fail condition is <17 in the meter (max is 24) * Sound Voltex * - Sound Voltex uses the note accuracy list slots as follows: * Early: * Error - Marvelous * Near - Perfect * Critical - Great * S-Critical - Good * Critical - Bad * Near - OK * Error - Miss * - Sound Voltex stores EX score in Percentage. * - Max Combo is Max Chain * - Sound Voltex will store additional data about accuracy of note types as such: * {"chip":{"scritical":0,"critical":0,"near":0,"error":0},"long":{"scritical":0,"error":0},"vol":{"scritical":0,"error":0},"gauge":,"gauge_pct":100} * //Also storing what type of clear gauge was met and the % of the gauge. * - Fail condition is <70% normal gauge. * IIDX * - Not going to support right now. * */ static int testCount=0; static int testsSucceeded=0; final static int DDR_AAA=0; final static int DDR_AAPLUS=1; final static int DDR_AA=2; final static int DDR_AAMINUS=3; final static int DDR_APLUS=4; final static int DDR_A=5; final static int DDR_AMINUS=6; final static int DDR_BPLUS=7; final static int DDR_B=8; final static int DDR_BMINUS=9; final static int DDR_CPLUS=10; final static int DDR_C=11; final static int DDR_CMINUS=12; final static int DDR_DPLUS=13; final static int DDR_D=14; final static int DDR_E=15; final static int ITG_QUAD=0; final static int ITG_TRI=1; final static int ITG_DOUB=2; final static int ITG_STAR=3; final static int ITG_SPLUS=4; final static int ITG_S=5; final static int ITG_SMINUS=6; final static int ITG_APLUS=7; final static int ITG_A=8; final static int ITG_AMINUS=9; final static int ITG_BPLUS=10; final static int ITG_B=11; final static int ITG_BMINUS=12; final static int ITG_CPLUS=13; final static int ITG_C=14; final static int ITG_CMINUS=15; final static int ITG_D=16; final static int ITG_F=17; final static int LOVELIVE_SSS=0; final static int LOVELIVE_SS=1; final static int LOVELIVE_S=2; final static int LOVELIVE_A=3; final static int LOVELIVE_B=4; final static int LOVELIVE_C=5; final static int LOVELIVE_D=6; final static int POPN_S=0; final static int POPN_AAA=1; final static int POPN_AA=2; final static int POPN_A=3; final static int POPN_B=4; final static int POPN_C=5; final static int POPN_D=6; final static int POPN_E=7; final static int SDVX_S=0; final static int SDVX_AAAPLUS=1; final static int SDVX_AAA=2; final static int SDVX_AAPLUS=3; final static int SDVX_AA=4; final static int SDVX_APLUS=5; final static int SDVX_A=6; final static int SDVX_B=7; final static int SDVX_C=8; final static int SDVX_D=9; static Reader interpret(Path p) { BufferedImage img; try { img = ImageIO.read(p.toFile()); return interpret(img); } catch (IOException e) { e.printStackTrace(); } return null; } static Reader interpret(BufferedImage img) { if (img.getHeight()>img.getWidth()) { return new SoundVoltexReader(); } else { Color col1 = new Color(img.getRGB(31, 41),true); ColorRange range1 = new ColorRange(245,255,235,240,70,80); Color col2 = new Color(img.getRGB(27, 1012),true); ColorRange range2 = new ColorRange(245,255,160,170,195,205); if (range1.colorInRange(col1)) { return new PopnReader(); } if (col1.equals(Color.BLACK)) { return new DDRReader(); } if (col1.equals(Color.WHITE)) { return new ITGReader(); } if (range2.colorInRange(col2)) { return new LoveLiveReader(); } } return null; } static void test(String filename,Class reader,int score,int rank,int[] notes,int diff,double pct,int maxcombo){ test(filename,reader,score,rank,notes,diff,pct,maxcombo,""); } static void test(String filename,Class reader,int score,int rank,int[] notes,int diff,double pct,int maxcombo,String other){ testCount++; Reader r = interpret(Paths.get("tests",filename)); r.interpretBoxes(Paths.get("tests",filename),true); Reader compare = new TestReader(score,rank,notes,diff,pct,maxcombo,other); if (!reader.isInstance(r)) { ArcadeReader.err(new Exception("Test \""+filename+"\" Failed:\nExpected class type: "+reader+" \nActual:"+r.getClass())); return; } if (!compare.equals(r)) { ArcadeReader.err(new Exception("Test \""+filename+"\" Failed:\nExpected:"+compare+"\nActual:"+r)); return; } ArcadeReader.success(); } public static void err(Exception e){ System.out.println(e.getStackTrace()[0]); System.out.println(e.getMessage()); System.exit(1); } public static void success(){ testsSucceeded++; System.out.println(testsSucceeded+"/"+testCount+"passed!"); } public static void runTests() { test("ddr1.png",DDRReader.class, 994790/*score*/, DDR_AAA/*rank*/, new int[]{322,77,3,0,96,1,0}/*notes*/, 9/*difficulty*/, 0.0/*pct*/, 287/*maxcombo*/, "{\"ex\":1411,\"fast\":18,\"slow\":62,\"playstyle\":\"\",\"diff\":\"\"}"/*other*/); test("ddr2.png",DDRReader.class, 875800/*score*/, DDR_APLUS/*rank*/, new int[]{333,196,108,18,10,26,0}/*notes*/, 11/*difficulty*/, 0.0/*pct*/, 230/*maxcombo*/, "{\"ex\":1529,\"fast\":105,\"slow\":217,\"playstyle\":\"\",\"diff\":\"\"}"/*other*/); test("ddr3.png",DDRReader.class, 991000/*score*/, DDR_AAA/*rank*/, new int[]{414,100,10,1,83,0,0}/*notes*/, 9/*difficulty*/, 0.0/*pct*/, 526/*maxcombo*/, "{\"ex\":1701,\"fast\":16,\"slow\":95,\"playstyle\":\"\",\"diff\":\"\"}"/*other*/); test("ddr4.png",DDRReader.class, 959410/*score*/, DDR_AAPLUS/*rank*/, new int[]{518,187,53,0,49,10,0}/*notes*/, 10/*difficulty*/, 0.0/*pct*/, 310/*maxcombo*/, "{\"ex\":2128,\"fast\":158,\"slow\":82,\"playstyle\":\"\",\"diff\":\"\"}"/*other*/); test("ddr5.png",DDRReader.class, 996070/*score*/, DDR_AAA/*rank*/, new int[]{289,47,3,0,11,0,0}/*notes*/, 12/*difficulty*/, 0.0/*pct*/, 339/*maxcombo*/, "{\"ex\":997,\"fast\":14,\"slow\":36,\"playstyle\":\"\",\"diff\":\"\"}"/*other*/); test("ddr6.png",DDRReader.class, 995410/*score*/, DDR_AAA/*rank*/, new int[]{375,72,2,0,17,1,0}/*notes*/, 13/*difficulty*/, 0.0/*pct*/, 779/*maxcombo*/, "{\"ex\":1322,\"fast\":20,\"slow\":54,\"playstyle\":\"\",\"diff\":\"\"}"/*other*/); test("ddr7.png",DDRReader.class, 940300/*score*/, DDR_AA/*rank*/, new int[]{334,102,28,3,8,15,0}/*notes*/, 14/*difficulty*/, 0.0/*pct*/, 100/*maxcombo*/, "{\"ex\":1258,\"fast\":51,\"slow\":82,\"playstyle\":\"\",\"diff\":\"\"}"/*other*/); test("ddr8.png",DDRReader.class, 978970/*score*/, DDR_AAPLUS/*rank*/, new int[]{405,133,21,1,13,2,0}/*notes*/, 15/*difficulty*/, 0.0/*pct*/, 320/*maxcombo*/, "{\"ex\":1541,\"fast\":72,\"slow\":83,\"playstyle\":\"\",\"diff\":\"\"}"/*other*/); test("ddr9.png",DDRReader.class, 891770/*score*/, DDR_APLUS/*rank*/, new int[]{386,182,90,13,7,27,0}/*notes*/, 16/*difficulty*/, 0.0/*pct*/, 211/*maxcombo*/, "{\"ex\":1633,\"fast\":186,\"slow\":99,\"playstyle\":\"\",\"diff\":\"\"}"/*other*/); test("ddr10.png",DDRReader.class, 867270/*score*/, DDR_APLUS/*rank*/, new int[]{313,165,92,19,32,32,0}/*notes*/, 17/*difficulty*/, 0.0/*pct*/, 80/*maxcombo*/, "{\"ex\":1457,\"fast\":166,\"slow\":110,\"playstyle\":\"\",\"diff\":\"\"}"/*other*/); test("ddr11.png",DDRReader.class, 201760/*score*/, DDR_E/*rank*/, new int[]{74,39,23,10,2,18,0}/*notes*/, 18/*difficulty*/, 0.0/*pct*/, 65/*maxcombo*/, "{\"ex\":329,\"fast\":62,\"slow\":10,\"playstyle\":\"\",\"diff\":\"\"}"/*other*/); test("itg1.png",ITGReader.class, 8020/*score*/, ITG_APLUS/*rank*/, new int[]{683,258,354,116,6,18,0}/*notes*/, 12/*difficulty*/, 87.28/*pct*/, 0/*maxcombo*/); test("itg2.png",ITGReader.class, 7563/*score*/, ITG_AMINUS/*rank*/, new int[]{591,246,405,152,1,36,0}/*notes*/, 12/*difficulty*/, 80.40/*pct*/, 0/*maxcombo*/); test("itg3.png",ITGReader.class, 8012/*score*/, ITG_AMINUS/*rank*/, new int[]{653,244,344,59,3,42,0}/*notes*/, 12/*difficulty*/, 81.90/*pct*/, 0/*maxcombo*/); test("itg4.png",ITGReader.class, 8228/*score*/, ITG_A/*rank*/, new int[]{1480,551,679,92,5,72,0}/*notes*/, 12/*difficulty*/, 84.95/*pct*/, 0/*maxcombo*/); test("itg5.png",ITGReader.class, 6241/*score*/, ITG_F/*rank*/, new int[]{482,185,206,79,10,42,0}/*notes*/, 12/*difficulty*/, 60.95/*pct*/, 0/*maxcombo*/); test("itg6.png",ITGReader.class, 8069/*score*/, ITG_APLUS/*rank*/, new int[]{252,99,141,30,2,5,0}/*notes*/, 12/*difficulty*/, 88.03/*pct*/, 0/*maxcombo*/); test("itg7.png",ITGReader.class, 9170/*score*/, ITG_STAR/*rank*/, new int[]{209,58,36,1,1,0,0}/*notes*/, 10/*difficulty*/, 97.16/*pct*/, 0/*maxcombo*/); test("itg8.png",ITGReader.class, 9008/*score*/, ITG_SPLUS/*rank*/, new int[]{319,75,65,8,3,0,0}/*notes*/, 13/*difficulty*/, 95.79/*pct*/, 0/*maxcombo*/); test("itg9.png",ITGReader.class, 9032/*score*/, ITG_STAR/*rank*/, new int[]{445,100,95,11,1,0,0}/*notes*/, 14/*difficulty*/, 96.08/*pct*/, 0/*maxcombo*/); test("itg10.png",ITGReader.class, 6921/*score*/, ITG_B/*rank*/, new int[]{247,108,172,113,27,13,0}/*notes*/, 15/*difficulty*/, 74.72/*pct*/, 0/*maxcombo*/); test("itg11.png",ITGReader.class, 6921/*score*/, ITG_B/*rank*/, new int[]{247,108,172,113,27,13,0}/*notes*/, 15/*difficulty*/, 74.72/*pct*/, 0/*maxcombo*/); test("itg12.png",ITGReader.class, 3829/*score*/, ITG_F/*rank*/, new int[]{151,72,80,50,6,17,0}/*notes*/, 16/*difficulty*/, 37.37/*pct*/, 0/*maxcombo*/); test("itg13.png",ITGReader.class, 0/*score*/, ITG_F/*rank*/, new int[]{0,0,0,0,0,6,0}/*notes*/, 17/*difficulty*/, 0.0/*pct*/, 0/*maxcombo*/); test("itg14.png",ITGReader.class, 0/*score*/, ITG_F/*rank*/, new int[]{0,0,0,0,0,6,0}/*notes*/, 18/*difficulty*/, 0.0/*pct*/, 0/*maxcombo*/); test("itg15.png",ITGReader.class, 9497/*score*/, ITG_DOUB/*rank*/, new int[]{215,40,17,0,1,0,0}/*notes*/, 9/*difficulty*/, 98.49/*pct*/, 0/*maxcombo*/); test("lovelive1.png",LoveLiveReader.class, 325415/*score*/, LOVELIVE_SSS/*rank*/, new int[]{539,4,0,0,0,0,0}/*notes*/, 0/*difficulty*/, 119.8/*pct*/, 543/*maxcombo*/); test("lovelive2.png",LoveLiveReader.class, 331923/*score*/, LOVELIVE_SS/*rank*/, new int[]{514,96,0,0,0,0,0}/*notes*/, 0/*difficulty*/, 116.8/*pct*/, 610/*maxcombo*/); test("lovelive3.png",LoveLiveReader.class, 282182/*score*/, LOVELIVE_SS/*rank*/, new int[]{573,45,4,3,8,0,0}/*notes*/, 0/*difficulty*/, 115.9/*pct*/, 334/*maxcombo*/); test("lovelive4.png",LoveLiveReader.class, 282182/*score*/, LOVELIVE_SS/*rank*/, new int[]{573,45,4,3,8,0,0}/*notes*/, 0/*difficulty*/, 115.9/*pct*/, 334/*maxcombo*/); test("lovelive5.png",LoveLiveReader.class, 19454/*score*/, LOVELIVE_SS/*rank*/, new int[]{117,11,1,0,0,0,0}/*notes*/, 0/*difficulty*/, 117.5/*pct*/, 74/*maxcombo*/); test("lovelive6.png",LoveLiveReader.class, 290746/*score*/, LOVELIVE_SS/*rank*/, new int[]{525,104,0,1,1,0,0}/*notes*/, 0/*difficulty*/, 116.3/*pct*/, 427/*maxcombo*/); test("lovelive7.png",LoveLiveReader.class, 0/*score*/, LOVELIVE_D/*rank*/, new int[]{0,0,0,0,0,0,0}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 0/*maxcombo*/); test("lovelive8.png",LoveLiveReader.class, 140879/*score*/, LOVELIVE_A/*rank*/, new int[]{445,16,0,0,1,0,0}/*notes*/, 0/*difficulty*/, 119.0/*pct*/, 237/*maxcombo*/); test("lovelive9.png",LoveLiveReader.class, 183644/*score*/, LOVELIVE_SSS/*rank*/, new int[]{452,10,0,0,0,0,0}/*notes*/, 0/*difficulty*/, 119.5/*pct*/, 462/*maxcombo*/); test("lovelive10.png",LoveLiveReader.class, 143468/*score*/, LOVELIVE_S/*rank*/, new int[]{410,12,0,1,37,0,0}/*notes*/, 0/*difficulty*/, 109.1/*pct*/, 334/*maxcombo*/); test("lovelive11.png",LoveLiveReader.class, 100456/*score*/, LOVELIVE_B/*rank*/, new int[]{303,17,0,0,119,0,0}/*notes*/, 0/*difficulty*/, 82.3/*pct*/, 235/*maxcombo*/); test("lovelive12.png",LoveLiveReader.class, 70288/*score*/, LOVELIVE_C/*rank*/, new int[]{197,16,0,0,206,0,0}/*notes*/, 0/*difficulty*/, 54.6/*pct*/, 213/*maxcombo*/); test("popn1.png",PopnReader.class, 83520/*score*/, POPN_A/*rank*/, new int[]{495,238,54,44,0,0,0}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 78/*maxcombo*/, "{\"failed\":false}"/*other*/); test("popn2.png",PopnReader.class, 81259/*score*/, POPN_B/*rank*/, new int[]{482,310,91,36,0,0,0}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 112/*maxcombo*/, "{\"failed\":false}"/*other*/); test("popn3.png",PopnReader.class, 79269/*score*/, POPN_B/*rank*/, new int[]{481,396,112,37,0,0,0}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 99/*maxcombo*/, "{\"failed\":false}"/*other*/); test("popn4.png",PopnReader.class, 80911/*score*/, POPN_B/*rank*/, new int[]{485,322,89,40,0,0,0}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 157/*maxcombo*/, "{\"failed\":false}"/*other*/); test("popn5.png",PopnReader.class, 78495/*score*/, POPN_B/*rank*/, new int[]{425,297,127,35,0,0,0}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 127/*maxcombo*/, "{\"failed\":false}"/*other*/); test("popn6.png",PopnReader.class, 80173/*score*/, POPN_B/*rank*/, new int[]{438,305,101,26,0,0,0}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 153/*maxcombo*/, "{\"failed\":false}"/*other*/); test("popn7.png",PopnReader.class, 79907/*score*/, POPN_B/*rank*/, new int[]{474,369,107,34,0,0,0}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 122/*maxcombo*/, "{\"failed\":false}"/*other*/); test("popn8.png",PopnReader.class, 80814/*score*/, POPN_B/*rank*/, new int[]{496,286,96,50,0,0,0}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 103/*maxcombo*/, "{\"failed\":false}"/*other*/); test("popn9.png",PopnReader.class, 82848/*score*/, POPN_A/*rank*/, new int[]{528,322,80,28,0,0,0}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 202/*maxcombo*/, "{\"failed\":false}"/*other*/); test("popn10.png",PopnReader.class, 81631/*score*/, POPN_B/*rank*/, new int[]{532,342,98,32,0,0,0}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 145/*maxcombo*/, "{\"failed\":false}"/*other*/); test("popn11.png",PopnReader.class, 80875/*score*/, POPN_B/*rank*/, new int[]{500,310,102,36,0,0,0}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 123/*maxcombo*/, "{\"failed\":false}"/*other*/); test("popn12.png",PopnReader.class, 81600/*score*/, POPN_B/*rank*/, new int[]{524,339,98,33,0,0,0}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 199/*maxcombo*/, "{\"failed\":false}"/*other*/); test("popn13.png",PopnReader.class, 87204/*score*/, POPN_A/*rank*/, new int[]{665,293,55,18,0,0,0}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 420/*maxcombo*/, "{\"failed\":false}"/*other*/); test("popn14.png",PopnReader.class, 83279/*score*/, POPN_A/*rank*/, new int[]{493,285,78,27,0,0,0}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 332/*maxcombo*/, "{\"failed\":false}"/*other*/); test("popn15.png",PopnReader.class, 86786/*score*/, POPN_A/*rank*/, new int[]{439,215,32,9,0,0,0}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 276/*maxcombo*/, "{\"failed\":false}"/*other*/); test("sdvx1.png",SoundVoltexReader.class, 3019559/*score*/, SDVX_D/*rank*/, new int[]{13,59,31,495,34,56,582}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 233/*maxcombo*/, "{\"ex\":1696,\"chip_scritical\":72,\"chip_critical\":65,\"chip_near\":115,\"chip_error\":240,\"long_scritical\":79,\"long_error\":93,\"vol_scritical\":344,\"vol_error\":262,\"failed\":true}"/*other*/); test("sdvx2.png",SoundVoltexReader.class, 2060643/*score*/, SDVX_D/*rank*/, new int[]{0,3,2,160,3,0,109}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 87/*maxcombo*/, "{\"ex\":361,\"chip_scritical\":5,\"chip_critical\":5,\"chip_near\":3,\"chip_error\":26,\"long_scritical\":53,\"long_error\":79,\"vol_scritical\":102,\"vol_error\":4,\"failed\":true}"/*other*/); test("sdvx3.png",SoundVoltexReader.class, 8759328/*score*/, SDVX_A/*rank*/, new int[]{14,88,141,1460,155,156,130}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 257/*maxcombo*/, "{\"ex\":5816,\"chip_scritical\":408,\"chip_critical\":296,\"chip_near\":244,\"chip_error\":67,\"long_scritical\":423,\"long_error\":11,\"vol_scritical\":629,\"vol_error\":66,\"failed\":true}"/*other*/); test("sdvx4.png",SoundVoltexReader.class, 9129755/*score*/, SDVX_APLUS/*rank*/, new int[]{7,84,94,1474,99,86,75}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 234/*maxcombo*/, "{\"ex\":4882,\"chip_scritical\":274,\"chip_critical\":193,\"chip_near\":170,\"chip_error\":32,\"long_scritical\":308,\"long_error\":13,\"vol_scritical\":892,\"vol_error\":37,\"failed\":true}"/*other*/); test("sdvx5.png",SoundVoltexReader.class, 9653667/*score*/, SDVX_AAPLUS/*rank*/, new int[]{1,53,88,1517,21,12,26}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 593/*maxcombo*/, "{\"ex\":4119,\"chip_scritical\":173,\"chip_critical\":109,\"chip_near\":65,\"chip_error\":4,\"long_scritical\":375,\"long_error\":1,\"vol_scritical\":969,\"vol_error\":22,\"failed\":false}"/*other*/); test("sdvx6.png",SoundVoltexReader.class, 9498351/*score*/, SDVX_AA/*rank*/, new int[]{2,70,142,1782,43,29,55}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 372/*maxcombo*/, "{\"ex\":5525,\"chip_scritical\":341,\"chip_critical\":185,\"chip_near\":99,\"chip_error\":8,\"long_scritical\":345,\"long_error\":17,\"vol_scritical\":1096,\"vol_error\":32,\"failed\":false}"/*other*/); test("sdvx7.png",SoundVoltexReader.class, 9498351/*score*/, SDVX_AA/*rank*/, new int[]{2,70,142,1782,43,29,55}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 372/*maxcombo*/, "{\"ex\":5525,\"chip_scritical\":341,\"chip_critical\":185,\"chip_near\":99,\"chip_error\":8,\"long_scritical\":345,\"long_error\":17,\"vol_scritical\":1096,\"vol_error\":32,\"failed\":false}"/*other*/); test("sdvx8.png",SoundVoltexReader.class, 725020/*score*/, SDVX_D/*rank*/, new int[]{8,15,4,148,11,16,706}/*notes*/, 0/*difficulty*/, 0.0/*pct*/, 21/*maxcombo*/, "{\"ex\":457,\"chip_scritical\":13,\"chip_critical\":15,\"chip_near\":31,\"chip_error\":201,\"long_scritical\":44,\"long_error\":241,\"vol_scritical\":91,\"vol_error\":272,\"failed\":true}"/*other*/); } public static int getScore(String record) { String searchString = "\"score\":"; int index = record.indexOf(searchString)+searchString.length(); int endIndex=record.indexOf(",",index); return Integer.parseInt(record.substring(index,endIndex)); } public static String convertTitle(String str) { return str.replaceAll(Pattern.quote("#"),"") .replaceAll(Pattern.quote("%"),"") .replaceAll(Pattern.quote("&"),"") .replaceAll(Pattern.quote("{"),"") .replaceAll(Pattern.quote("}"),"") .replaceAll(Pattern.quote("\\"),"") .replaceAll(Pattern.quote("<"),"") .replaceAll(Pattern.quote(">"),"") .replaceAll(Pattern.quote("*"),"") .replaceAll(Pattern.quote("\""),"") .replaceAll(Pattern.quote("?"),"") .replaceAll(Pattern.quote("'"),"") .replaceAll(Pattern.quote("/"),"") .replaceAll(Pattern.quote("$"),"") .replaceAll(Pattern.quote("!"),"") .replaceAll(Pattern.quote(":"),"") .replaceAll(Pattern.quote("@"),"") .replaceAll(Pattern.quote("+"),"") .replaceAll(Pattern.quote("`"),"") .replaceAll(Pattern.quote("|"),"") .replaceAll(Pattern.quote("="),""); } public static void submitToDatabase(Path p) { Thread t = new Thread(){ public void run() { //First we read and interpret what this image is. BufferedImage img; try { img = ImageIO.read(p.toFile()); final Reader newImg = interpret(img); newImg.result_screenshot=p; //Path getGamePath = gamePath(newImg); newImg.interpretBoxes(p); HashMap>> DATA = sigPlace.SONG_DATABASE; List RECENT_PLAYS = sigPlace.RECENT_PLAYS; List RECENT_RECORDS = sigPlace.RECENT_RECORDS; HashMap> SONG_DATA=DATA.getOrDefault(newImg.getClass().getSimpleName(),new HashMap<>()); List RECORDS = SONG_DATA.getOrDefault(convertTitle(newImg.getTitle()),new ArrayList<>()); boolean found=false; for (int i=0;i20) { RECENT_PLAYS.remove(RECENT_PLAYS.size()-1); } RECORDS.add(i, newImg.toStringWithScreenshot()); break; } } if (!found) { RECORDS.add(newImg.toStringWithScreenshot()); RECENT_RECORDS.add(0,newImg.toStringWithScreenshot()); RECENT_PLAYS.add(0,newImg.toStringWithScreenshot()); if (RECENT_PLAYS.size()>20) { RECENT_PLAYS.remove(RECENT_PLAYS.size()-1); } } if (RECENT_RECORDS.size()>20) { RECENT_RECORDS.remove(RECENT_RECORDS.size()-1); } SONG_DATA.put(convertTitle(newImg.getTitle()),RECORDS); DATA.put(newImg.getClass().getSimpleName(),SONG_DATA); //Threaded database update. for (String reader : sigPlace.SONG_DATABASE.keySet()) { for (String song : sigPlace.SONG_DATABASE.get(reader).keySet()) { List data = sigPlace.SONG_DATABASE.get(reader).get(song); try { Files.createDirectories(Paths.get("database",reader)); Files.write(Paths.get("database",reader,song), data, Charset.defaultCharset(), StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING,StandardOpenOption.WRITE); } catch (IOException e) { e.printStackTrace(); } } } List data = sigPlace.RECENT_PLAYS; try { Files.write(Paths.get("database","recentplays"), data, Charset.defaultCharset(), StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING,StandardOpenOption.WRITE); } catch (IOException e) { e.printStackTrace(); } data = sigPlace.RECENT_RECORDS; try { Files.write(Paths.get("database","recentrecords"), data, Charset.defaultCharset(), StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING,StandardOpenOption.WRITE); } catch (IOException e) { e.printStackTrace(); } } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }; t.start(); } }