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){
|
||||
rawJson = json;
|
||||
id = json["_id"];
|
||||
endcontext = [EndContextMulti.fromJson(json["endcontext"][0]), EndContextMulti.fromJson(json["endcontext"][1])];
|
||||
id = json['_id'];
|
||||
endcontext = [EndContextMulti.fromJson(json['endcontext'][0]), EndContextMulti.fromJson(json['endcontext'][1])];
|
||||
roundLengths = [];
|
||||
totalLength = 0;
|
||||
stats = [];
|
||||
roundWinners = [];
|
||||
totalStats = [ReplayStats.createEmpty(), ReplayStats.createEmpty()];
|
||||
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 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);
|
||||
for(var round in json['data']) {
|
||||
roundLengths.add(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);
|
||||
roundWinners.add([round['board'][winner]["id"], round['board'][winner]["username"]]);
|
||||
int winner = round['board'].indexWhere((element) => element['success'] == true);
|
||||
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 playerTwo = ReplayStats.fromJson(round['replays'][secondInEndContext]['events'].last['data']['export']['stats'], biggestSpikeFromReplay(round['replays'][firstInEndContext]['events']));
|
||||
stats.add([playerOne, playerTwo]);
|
||||
|
@ -185,4 +185,22 @@ class ReplayData{
|
|||
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(createTetrioUsersToTrack);
|
||||
await db.execute(createTetrioTLRecordsTable);
|
||||
await db.execute(createTetrioTLReplayStats);
|
||||
} on MissingPlatformDirectoryException {
|
||||
throw UnableToGetDocuments();
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ const String dbName = "TetraStats.db";
|
|||
const String tetrioUsersTable = "tetrioUsers";
|
||||
const String tetrioUsersToTrackTable = "tetrioUsersToTrack";
|
||||
const String tetraLeagueMatchesTable = "tetrioAlphaLeagueMathces";
|
||||
const String tetrioTLReplayStatsTable = "tetrioTLReplayStats";
|
||||
const String idCol = "id";
|
||||
const String replayID = "replayId";
|
||||
const String nickCol = "nickname";
|
||||
|
@ -53,10 +54,9 @@ const String createTetrioTLRecordsTable = '''
|
|||
''';
|
||||
|
||||
const String createTetrioTLReplayStats = '''
|
||||
CREATE TABLE "tetrioTLReplayStats" (
|
||||
CREATE TABLE IF NOT EXISTS "tetrioTLReplayStats" (
|
||||
"id" TEXT NOT NULL,
|
||||
"player1" TEXT NOT NULL,
|
||||
"player2" TEXT NOT NULL,
|
||||
"data" TEXT NOT NULL,
|
||||
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 {
|
||||
try{
|
||||
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();
|
||||
downloadPath ??= Platform.isAndroid ? Directory("/storage/emulated/0/Download") : await getApplicationDocumentsDirectory();
|
||||
var replayFile = File("${downloadPath.path}/$replayID.ttrm");
|
||||
|
@ -175,8 +181,14 @@ class TetrioService extends DB {
|
|||
}
|
||||
|
||||
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]);
|
||||
return ReplayData.fromJson(toAnalyze);
|
||||
ReplayData data = ReplayData.fromJson(toAnalyze);
|
||||
saveReplayStats(data);
|
||||
return data;
|
||||
}
|
||||
|
||||
Future<double?> fetchTopTR(String id) async {
|
||||
|
|
|
@ -93,7 +93,7 @@ class TlMatchResultState extends State<TlMatchResultView> {
|
|||
//anchor.remove();
|
||||
} else{
|
||||
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))));
|
||||
} on TetrioReplayAlreadyExist{
|
||||
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,
|
||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].linesCleared : snapshot.data!.stats[roundSelector][redSidePlayer].linesCleared,
|
||||
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,
|
||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].finessePercentage * 100 : snapshot.data!.stats[roundSelector][redSidePlayer].finessePercentage * 100,
|
||||
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,
|
||||
redSide: roundSelector.isNegative ? snapshot.data!.totalStats[redSidePlayer].garbage.cleared : snapshot.data!.stats[roundSelector][redSidePlayer].garbage.cleared,
|
||||
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{
|
||||
return Text("skill issue");
|
||||
return Container();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue