Now data is stored in local DB
ToDo: polish things and release of 1.4.0
This commit is contained in:
parent
39569ffe0c
commit
3807c7321e
|
@ -164,20 +164,20 @@ class ReplayData{
|
||||||
|
|
||||||
ReplayData.fromJson(Map<String, dynamic> json){
|
ReplayData.fromJson(Map<String, dynamic> json){
|
||||||
rawJson = json;
|
rawJson = json;
|
||||||
id = json["_id"];
|
id = json['_id'];
|
||||||
endcontext = [EndContextMulti.fromJson(json["endcontext"][0]), EndContextMulti.fromJson(json["endcontext"][1])];
|
endcontext = [EndContextMulti.fromJson(json['endcontext'][0]), EndContextMulti.fromJson(json['endcontext'][1])];
|
||||||
roundLengths = [];
|
roundLengths = [];
|
||||||
totalLength = 0;
|
totalLength = 0;
|
||||||
stats = [];
|
stats = [];
|
||||||
roundWinners = [];
|
roundWinners = [];
|
||||||
totalStats = [ReplayStats.createEmpty(), ReplayStats.createEmpty()];
|
totalStats = [ReplayStats.createEmpty(), ReplayStats.createEmpty()];
|
||||||
int firstInEndContext = json["data"][0]["board"].indexWhere((element) => element["id"] == endcontext[0].userId);
|
int firstInEndContext = json['data'][0]['board'].indexWhere((element) => element['id'] == endcontext[0].userId);
|
||||||
int secondInEndContext = json["data"][0]["board"].indexWhere((element) => element["id"] == endcontext[1].userId);
|
int secondInEndContext = json['data'][0]['board'].indexWhere((element) => element['id'] == endcontext[1].userId);
|
||||||
for(var round in json['data']) {
|
for(var round in json['data']) {
|
||||||
roundLengths.add(max(round['replays'][0]['frames'], round['replays'][1]['frames']));
|
roundLengths.add(max(round['replays'][0]['frames'], round['replays'][1]['frames']));
|
||||||
totalLength = totalLength + max(round['replays'][0]['frames'], round['replays'][1]['frames']);
|
totalLength = totalLength + max(round['replays'][0]['frames'], round['replays'][1]['frames']);
|
||||||
int winner = round['board'].indexWhere((element) => element["success"] == true);
|
int winner = round['board'].indexWhere((element) => element['success'] == true);
|
||||||
roundWinners.add([round['board'][winner]["id"], round['board'][winner]["username"]]);
|
roundWinners.add([round['board'][winner]['id'], round['board'][winner]['username']]);
|
||||||
ReplayStats playerOne = ReplayStats.fromJson(round['replays'][firstInEndContext]['events'].last['data']['export']['stats'], biggestSpikeFromReplay(round['replays'][secondInEndContext]['events'])); // (events contain recived attacks)
|
ReplayStats playerOne = ReplayStats.fromJson(round['replays'][firstInEndContext]['events'].last['data']['export']['stats'], biggestSpikeFromReplay(round['replays'][secondInEndContext]['events'])); // (events contain recived attacks)
|
||||||
ReplayStats playerTwo = ReplayStats.fromJson(round['replays'][secondInEndContext]['events'].last['data']['export']['stats'], biggestSpikeFromReplay(round['replays'][firstInEndContext]['events']));
|
ReplayStats playerTwo = ReplayStats.fromJson(round['replays'][secondInEndContext]['events'].last['data']['export']['stats'], biggestSpikeFromReplay(round['replays'][firstInEndContext]['events']));
|
||||||
stats.add([playerOne, playerTwo]);
|
stats.add([playerOne, playerTwo]);
|
||||||
|
@ -185,4 +185,22 @@ class ReplayData{
|
||||||
totalStats[1] = totalStats[1] + playerTwo;
|
totalStats[1] = totalStats[1] + playerTwo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson(){
|
||||||
|
final Map<String, dynamic> data = <String, dynamic>{};
|
||||||
|
data['_id'] = id;
|
||||||
|
data['endcontext'] = [endcontext[0].toJson(), endcontext[1].toJson()];
|
||||||
|
data['data'] = [];
|
||||||
|
for(var round in rawJson['data']) {
|
||||||
|
List<dynamic> eventsPlayerOne = round['replays'][0]['events'];
|
||||||
|
List<dynamic> eventsPlayerTwo = round['replays'][1]['events'];
|
||||||
|
eventsPlayerOne.removeWhere((v) => (v['type'] == 'ige' && v['data']['data']['type'] != 'interaction') || (v['type'] != 'end' && v['type'] != 'ige'));
|
||||||
|
eventsPlayerTwo.removeWhere((v) => (v['type'] == 'ige' && v['data']['data']['type'] != 'interaction') || (v['type'] != 'end' && v['type'] != 'ige'));
|
||||||
|
data['data'].add({'board': round['board'], 'replays': [
|
||||||
|
{'frames': round['replays'][0]['frames'], 'events': eventsPlayerOne},
|
||||||
|
{'frames': round['replays'][1]['frames'], 'events': eventsPlayerTwo}
|
||||||
|
]});
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -28,6 +28,7 @@ class DB {
|
||||||
await db.execute(createTetrioUsersTable);
|
await db.execute(createTetrioUsersTable);
|
||||||
await db.execute(createTetrioUsersToTrack);
|
await db.execute(createTetrioUsersToTrack);
|
||||||
await db.execute(createTetrioTLRecordsTable);
|
await db.execute(createTetrioTLRecordsTable);
|
||||||
|
await db.execute(createTetrioTLReplayStats);
|
||||||
} on MissingPlatformDirectoryException {
|
} on MissingPlatformDirectoryException {
|
||||||
throw UnableToGetDocuments();
|
throw UnableToGetDocuments();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ const String dbName = "TetraStats.db";
|
||||||
const String tetrioUsersTable = "tetrioUsers";
|
const String tetrioUsersTable = "tetrioUsers";
|
||||||
const String tetrioUsersToTrackTable = "tetrioUsersToTrack";
|
const String tetrioUsersToTrackTable = "tetrioUsersToTrack";
|
||||||
const String tetraLeagueMatchesTable = "tetrioAlphaLeagueMathces";
|
const String tetraLeagueMatchesTable = "tetrioAlphaLeagueMathces";
|
||||||
|
const String tetrioTLReplayStatsTable = "tetrioTLReplayStats";
|
||||||
const String idCol = "id";
|
const String idCol = "id";
|
||||||
const String replayID = "replayId";
|
const String replayID = "replayId";
|
||||||
const String nickCol = "nickname";
|
const String nickCol = "nickname";
|
||||||
|
@ -53,10 +54,9 @@ const String createTetrioTLRecordsTable = '''
|
||||||
''';
|
''';
|
||||||
|
|
||||||
const String createTetrioTLReplayStats = '''
|
const String createTetrioTLReplayStats = '''
|
||||||
CREATE TABLE "tetrioTLReplayStats" (
|
CREATE TABLE IF NOT EXISTS "tetrioTLReplayStats" (
|
||||||
"id" TEXT NOT NULL,
|
"id" TEXT NOT NULL,
|
||||||
"player1" TEXT NOT NULL,
|
"data" TEXT NOT NULL,
|
||||||
"player2" TEXT NOT NULL,
|
|
||||||
PRIMARY KEY("id")
|
PRIMARY KEY("id")
|
||||||
)
|
)
|
||||||
''';
|
''';
|
||||||
|
@ -121,6 +121,12 @@ class TetrioService extends DB {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> saveReplayStats(ReplayData replay) async {
|
||||||
|
await ensureDbIsOpen();
|
||||||
|
final db = getDatabaseOrThrow();
|
||||||
|
db.insert(tetrioTLReplayStatsTable, {idCol: replay.id, "data": jsonEncode(replay.toJson())});
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<dynamic>> szyGetReplay(String replayID) async {
|
Future<List<dynamic>> szyGetReplay(String replayID) async {
|
||||||
try{
|
try{
|
||||||
var cached = _replaysCache.entries.firstWhere((element) => element.key == replayID);
|
var cached = _replaysCache.entries.firstWhere((element) => element.key == replayID);
|
||||||
|
@ -164,7 +170,7 @@ class TetrioService extends DB {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<String> SaveReplay(String replayID) async {
|
Future<String> saveReplay(String replayID) async {
|
||||||
var downloadPath = await getDownloadsDirectory();
|
var downloadPath = await getDownloadsDirectory();
|
||||||
downloadPath ??= Platform.isAndroid ? Directory("/storage/emulated/0/Download") : await getApplicationDocumentsDirectory();
|
downloadPath ??= Platform.isAndroid ? Directory("/storage/emulated/0/Download") : await getApplicationDocumentsDirectory();
|
||||||
var replayFile = File("${downloadPath.path}/$replayID.ttrm");
|
var replayFile = File("${downloadPath.path}/$replayID.ttrm");
|
||||||
|
@ -175,8 +181,14 @@ class TetrioService extends DB {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ReplayData> analyzeReplay(String replayID) async{
|
Future<ReplayData> analyzeReplay(String replayID) async{
|
||||||
|
await ensureDbIsOpen();
|
||||||
|
final db = getDatabaseOrThrow();
|
||||||
|
final results = await db.query(tetrioTLReplayStatsTable, where: '$idCol = ?', whereArgs: [replayID]);
|
||||||
|
if (results.isNotEmpty) return ReplayData.fromJson(jsonDecode(results.first["data"].toString()));
|
||||||
Map<String, dynamic> toAnalyze = jsonDecode((await szyGetReplay(replayID))[0]);
|
Map<String, dynamic> toAnalyze = jsonDecode((await szyGetReplay(replayID))[0]);
|
||||||
return ReplayData.fromJson(toAnalyze);
|
ReplayData data = ReplayData.fromJson(toAnalyze);
|
||||||
|
saveReplayStats(data);
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<double?> fetchTopTR(String id) async {
|
Future<double?> fetchTopTR(String id) async {
|
||||||
|
|
|
@ -93,7 +93,7 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
||||||
//anchor.remove();
|
//anchor.remove();
|
||||||
} else{
|
} else{
|
||||||
try{
|
try{
|
||||||
String path = await teto.SaveReplay(widget.record.replayId);
|
String path = await teto.saveReplay(widget.record.replayId);
|
||||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.replaySaved(path: path))));
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.replaySaved(path: path))));
|
||||||
} on TetrioReplayAlreadyExist{
|
} on TetrioReplayAlreadyExist{
|
||||||
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.errors.replayAlreadySaved)));
|
ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(t.errors.replayAlreadySaved)));
|
||||||
|
@ -264,6 +264,9 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].linesCleared : snapshot.data!.stats[roundSelector][greenSidePlayer].linesCleared,
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].linesCleared : snapshot.data!.stats[roundSelector][greenSidePlayer].linesCleared,
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].linesCleared : snapshot.data!.stats[roundSelector][redSidePlayer].linesCleared,
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].linesCleared : snapshot.data!.stats[roundSelector][redSidePlayer].linesCleared,
|
||||||
label: "Lines Cleared", higherIsBetter: true),
|
label: "Lines Cleared", higherIsBetter: true),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].score : snapshot.data!.stats[roundSelector][greenSidePlayer].score,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].score : snapshot.data!.stats[roundSelector][redSidePlayer].score,
|
||||||
|
label: "Score", higherIsBetter: true),
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].finessePercentage * 100 : snapshot.data!.stats[roundSelector][greenSidePlayer].finessePercentage * 100,
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].finessePercentage * 100 : snapshot.data!.stats[roundSelector][greenSidePlayer].finessePercentage * 100,
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].finessePercentage * 100 : snapshot.data!.stats[roundSelector][redSidePlayer].finessePercentage * 100,
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].finessePercentage * 100 : snapshot.data!.stats[roundSelector][redSidePlayer].finessePercentage * 100,
|
||||||
label: "Finnese", postfix: "%", fractionDigits: 2, higherIsBetter: true),
|
label: "Finnese", postfix: "%", fractionDigits: 2, higherIsBetter: true),
|
||||||
|
@ -293,9 +296,23 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
||||||
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.cleared : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.cleared,
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].garbage.cleared : snapshot.data!.stats[roundSelector][greenSidePlayer].garbage.cleared,
|
||||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.cleared : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.cleared,
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.cleared : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.cleared,
|
||||||
label: "Cleared", higherIsBetter: true),
|
label: "Cleared", higherIsBetter: true),
|
||||||
|
const Divider(),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(bottom: 16),
|
||||||
|
child: Text("Line Clears", style: TextStyle(fontFamily: "Eurostile Round Extended", fontSize: bigScreen ? 42 : 28)),
|
||||||
|
),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].clears.allClears : snapshot.data!.stats[roundSelector][greenSidePlayer].clears.allClears,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].clears.allClears : snapshot.data!.stats[roundSelector][redSidePlayer].clears.allClears,
|
||||||
|
label: "PC", higherIsBetter: true),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].tspins : snapshot.data!.stats[roundSelector][greenSidePlayer].tspins,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].tspins : snapshot.data!.stats[roundSelector][redSidePlayer].tspins,
|
||||||
|
label: "T-spins", higherIsBetter: true),
|
||||||
|
CompareThingy(greenSide: roundSelector.isNegative ? snapshot.data!.totalStats[greenSidePlayer].clears.quads : snapshot.data!.stats[roundSelector][greenSidePlayer].clears.quads,
|
||||||
|
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].clears.quads : snapshot.data!.stats[roundSelector][redSidePlayer].clears.quads,
|
||||||
|
label: "Quads", higherIsBetter: true),
|
||||||
],);
|
],);
|
||||||
}else{
|
}else{
|
||||||
return Text("skill issue");
|
return Container();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue