|
|
|
@ -1,13 +1,111 @@ |
|
|
|
|
import java.io.IOException; |
|
|
|
|
import java.nio.file.Files; |
|
|
|
|
import java.nio.file.Path; |
|
|
|
|
import java.util.Base64; |
|
|
|
|
import java.io.InputStreamReader; |
|
|
|
|
import java.util.ArrayList; |
|
|
|
|
import java.util.List; |
|
|
|
|
import java.awt.image.BufferedImage; |
|
|
|
|
|
|
|
|
|
public class ArcadeReader { |
|
|
|
|
public static String fileToBase64String(Path file) { |
|
|
|
|
/* |
|
|
|
|
* 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. |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
public static void retrieveData(BufferedImage img) { |
|
|
|
|
new LoveLiveReader().interpretBoxes(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
class Box{ |
|
|
|
|
int x,y,w,h; |
|
|
|
|
boolean ja_required; |
|
|
|
|
final static int BOX_THRESHOLD=8; //How many pixels outside the specified region the score can be.
|
|
|
|
|
Box(int x,int y,int w, int h) { |
|
|
|
|
this.x=x; |
|
|
|
|
this.y=y; |
|
|
|
|
this.w=w; |
|
|
|
|
this.h=h; |
|
|
|
|
} |
|
|
|
|
boolean insideBox(int x,int y) { |
|
|
|
|
return this.x-BOX_THRESHOLD<=x&&this.x+this.w+BOX_THRESHOLD>=x&&this.y-BOX_THRESHOLD<=y&&this.y+this.h+BOX_THRESHOLD>=y; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
class LoveLiveReader extends Reader{ |
|
|
|
|
LoveLiveReader(){ |
|
|
|
|
readRegions.add(new Box(10,10,24,24)); |
|
|
|
|
readRegions.add(new Box(10,40,24,24)); |
|
|
|
|
readRegions.add(new Box(10,70,24,24)); |
|
|
|
|
} |
|
|
|
|
void interpretBoxes(){ |
|
|
|
|
String dataString = readAllBoxes(); |
|
|
|
|
System.out.println(dataString); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
abstract class Reader{ |
|
|
|
|
int score; |
|
|
|
|
int rank; |
|
|
|
|
int[] notes = new int[7]; |
|
|
|
|
int difficulty; |
|
|
|
|
String title; |
|
|
|
|
int pct; |
|
|
|
|
int maxcombo; |
|
|
|
|
String other; |
|
|
|
|
List<Box> readRegions = new ArrayList<>(); |
|
|
|
|
String readAllBoxes() { |
|
|
|
|
try { |
|
|
|
|
return Base64.getEncoder().encodeToString(Files.readAllBytes(file)); |
|
|
|
|
} catch(IOException e) { |
|
|
|
|
Process p = Runtime.getRuntime().exec("cat testBoxes.txt"); |
|
|
|
|
InputStreamReader result = new InputStreamReader(p.getInputStream()); |
|
|
|
|
StringBuilder sb = new StringBuilder(); |
|
|
|
|
while (result.ready()) { |
|
|
|
|
sb.append((char)result.read()); |
|
|
|
|
} |
|
|
|
|
result.close(); |
|
|
|
|
return sb.toString(); |
|
|
|
|
} catch (IOException e) { |
|
|
|
|
e.printStackTrace(); |
|
|
|
|
} |
|
|
|
|
return ""; |
|
|
|
|