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" : < excessive | normal > , "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 ) {
//First we read and interpret what this image is.
BufferedImage img ;
try {
img = ImageIO . read ( p . toFile ( ) ) ;
Reader newImg = interpret ( img ) ;
newImg . result_screenshot = p ;
//Path getGamePath = gamePath(newImg);
newImg . interpretBoxes ( p ) ;
HashMap < String , HashMap < String , List < String > > > DATA = sigPlace . SONG_DATABASE ;
List < String > RECENT_PLAYS = sigPlace . RECENT_PLAYS ;
List < String > RECENT_RECORDS = sigPlace . RECENT_RECORDS ;
HashMap < String , List < String > > SONG_DATA = DATA . getOrDefault ( newImg . getClass ( ) . getSimpleName ( ) , new HashMap < > ( ) ) ;
List < String > RECORDS = SONG_DATA . getOrDefault ( convertTitle ( newImg . getTitle ( ) ) , new ArrayList < > ( ) ) ;
boolean found = false ;
for ( int i = 0 ; i < RECORDS . size ( ) ; i + + ) {
String s = RECORDS . get ( i ) ;
int score = getScore ( s ) ;
if ( score < newImg . getScore ( ) ) {
//Insert here.
found = true ;
if ( i = = 0 ) {
RECENT_RECORDS . add ( 0 , newImg . toStringWithScreenshot ( ) ) ;
}
RECENT_PLAYS . add ( 0 , newImg . toStringWithScreenshot ( ) ) ;
if ( RECENT_PLAYS . size ( ) > 20 ) {
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 ) ;
new Thread ( ) {
public void run ( ) {
//Threaded database update.
for ( String reader : sigPlace . SONG_DATABASE . keySet ( ) ) {
for ( String song : sigPlace . SONG_DATABASE . get ( reader ) . keySet ( ) ) {
List < String > data = sigPlace . SONG_DATABASE . get ( reader ) . get ( song ) ;
try {
Files . write ( Paths . get ( "database" , reader , song ) , data , Charset . defaultCharset ( ) , StandardOpenOption . CREATE , StandardOpenOption . TRUNCATE_EXISTING , StandardOpenOption . WRITE ) ;
} catch ( IOException e ) {
e . printStackTrace ( ) ;
}
}
}
List < String > 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 ( ) ;
}
}
} . start ( ) ;
} catch ( IOException e ) {
e . printStackTrace ( ) ;
}
}
}