import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:libac_dart/nbt/Stream.dart'; import 'package:libacflutter/Constants.dart'; import 'package:pokedex/Consts.dart'; import 'package:pokedex/Session.dart'; import 'package:pokedex/pokemon.dart'; import 'package:pokedex/pokemonHelpers.dart'; import 'package:wakelock_plus/wakelock_plus.dart'; Future main(List args) async { runApp(CompletedGenerator()); return 0; } class CompletedGenerator extends StatefulWidget { const CompletedGenerator({super.key}); @override State createState() { return _completedGen(); } } class _completedGen extends State { @override Widget build(BuildContext context) { return MaterialApp(theme: ThemeData.dark(), home: MainGen()); } } class MainGen extends StatefulWidget { const MainGen({super.key}); @override State createState() { return _main(); } } class _main extends State { bool firstLaunch = true; double progress = 0; String statusMessage = ""; Generation gen = Generation.One; StringBuilder sb = StringBuilder(); int index = 0; Generation? currentGen; Pokemon? currentPokemon; int maxTasks = 5; int total = 0; int completed = 0; int state = 0; @override void didChangeDependencies() { if (firstLaunch) { firstLaunch = false; WakelockPlus.enable(); setState(() { statusMessage = "Warming up..."; progress = 0.0; }); Timer.periodic(Duration(milliseconds: 100), (x) async { if (state == 0) { sleep(Duration(seconds: 5)); statusMessage = "Acquiring game generation"; progress = 0.25; setState(() {}); state++; } else if (state == 1) { SessionData.resetHighestGenCache(); int highest = SessionData.highestGenID(); // Get actual generation gen = Generation.One; for (var _gen in Generation.values) { if (_gen.idStart < highest) { gen = _gen; } } statusMessage = "Generation acquired"; progress = 1.0; state++; setState(() {}); } else if (state == 2) { statusMessage = "Generation ${gen.name}"; progress = 0.0; state++; setState(() {}); } else if (state == 3) { statusMessage = "Analyzing Pokemon..."; index = 0; currentGen = null; state++; setState(() {}); } else if (state == 4) { maxTasks += Pokemon.values.length; sb = StringBuilder(); sb.append("# NOTE\n"); sb.append( "\nCurrent highest implemented generation: **${gen.name}**", ); sb.append("\n\n**This file is automatically generated**\n\n"); sb.append("# About\n\n"); sb.append( "This file is a checklist of what Pokemon are up to date with the implemented generations.\n", ); state++; setState(() {}); } else if ((state - index) == 5) { // Pokemon iteration task int iterNumber = state - 5; if (iterNumber >= Pokemon.values.length) { state++; setState(() {}); return; } var pokemon = Pokemon.values[iterNumber]; currentPokemon = pokemon; if (currentGen != pokemon.generation) { if (total > 0 && completed != total && completed > 0) { sb.append("\n- Completed $completed/$total\n"); } sb.append("\n# Generation ${pokemon.generation.name}\n\n"); currentGen = pokemon.generation; total = 0; completed = 0; } progress = index * 100 / Pokemon.values.length; statusMessage = ("- Analysis of pokemon ${pokemon.pokemonName} has begun"); bool upToDate = false; for (var loc in pokemon.locations) { if (loc.gameGen.index >= gen.index) { upToDate = true; } } bool dexUpToDate = false; for (var dex in pokemon.dexEntries) { if (dex.gameGen.index >= gen.index) { upToDate = true; } } if (pokemon.locations.isEmpty && pokemon.dexEntries.isEmpty) { sb.append("- [ ] ${pokemon.pokemonName}\n"); } else { if (upToDate || dexUpToDate) { if (pokemon.locations.isNotEmpty && pokemon.dexEntries.isNotEmpty) { sb.append("- [x] ${pokemon.pokemonName}\n"); completed++; } else if (pokemon.locations.isNotEmpty) { sb.append( "- [ ] ${pokemon.pokemonName} (MISSING DEX ENTRIES)\n", ); } else if (pokemon.dexEntries.isNotEmpty) { sb.append( "- [ ] ${pokemon.pokemonName} (MISSING LOCATION ENTRIES)\n", ); } } else { sb.append("- [ ] ${pokemon.pokemonName} (OUT OF DATE DATA)\n"); } } total++; index++; progress = progress / 100; // push it into a 0-1 range. state++; setState(() {}); } else if (state - index == 6) { // Task - write file currentPokemon = null; if (completed != total && completed > 0) { sb.append("\n- Completed $completed/$total\n"); } maxTasks += 3; statusMessage = "Saving to COMPLETED.md"; File complete = File("COMPLETED.md"); progress = 99.75; state++; setState(() {}); await complete.writeAsString(sb.toString()); } else if (state - index == 7) { statusMessage = "Data generation completed"; progress = 1.0; state++; setState(() {}); } else if (state - index == 8) { statusMessage = "Updating Latest Version manifest..."; await File("LATEST_VERSION").writeAsString(Constants.VERSION); state++; setState(() {}); } else if (state - index == 9) { await WakelockPlus.disable(); x.cancel(); sleep(Duration(seconds: 10)); exit(0); } }); } super.didChangeDependencies(); } Widget dexEntry() { if (currentPokemon == null) { return Text(""); } else { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Image.asset(currentPokemon!.toDexPath()), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("Type: ", style: TextStyle(fontSize: 24)), PokemonHelpers.getTypeWidgets(currentPokemon!), ], ), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "First Seen in Generation ${currentPokemon!.generation.name}", style: TextStyle(fontSize: 24), ), ], ), if (currentPokemon!.extraVariants.isNotEmpty) Text("Extra Variations: ", style: TextStyle(fontSize: 24)), if (currentPokemon!.extraVariants.isNotEmpty) PokemonHelpers.getVariations(currentPokemon!), SizedBox(height: 32), SingleChildScrollView( scrollDirection: Axis.horizontal, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: PokemonHelpers.getEvolutions(0, currentPokemon!), ), ), if (SessionData.enableDescription && currentPokemon!.dexEntries.isNotEmpty) Text("Description: ", style: TextStyle(fontSize: 24)), if (SessionData.enableDescription && currentPokemon!.dexEntries.isNotEmpty) PokemonHelpers.printDescription(currentPokemon!), SizedBox(height: 50), if (currentPokemon!.locations.isNotEmpty) Text("Where to find:", style: TextStyle(fontSize: 24)), if (currentPokemon!.locations.isNotEmpty) PokemonHelpers.printLocations(currentPokemon!), ], ); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text("Data Generator"), backgroundColor: LibACFlutterConstants.TITLEBAR_COLOR, ), body: Padding( padding: const EdgeInsets.all(8.0), child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( "PokeDex Version: ${Constants.VERSION}", style: TextStyle(fontSize: 24), ), SizedBox(height: 50), Text("Status: $statusMessage", style: TextStyle(fontSize: 24)), Text( "Progress: ${progress * 100}%", style: TextStyle(fontSize: 24), ), Text("Task $state/$maxTasks", style: TextStyle(fontSize: 24)), LinearProgressIndicator(value: progress, minHeight: 30), SizedBox(height: 10), dexEntry(), ], ), ), ), ); } }