Refactored
This commit is contained in:
parent
fc1f6189e6
commit
2714797fcc
BIN
images/token.png
Normal file
BIN
images/token.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
BIN
images/vault.png
Normal file
BIN
images/vault.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
|
|
@ -1,5 +1,6 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:mhunt_launcher/Backend/Structures.dart';
|
import 'package:mhunt_launcher/Backend/Structures.dart';
|
||||||
|
|
@ -7,63 +8,68 @@ import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'DebugHelper.dart';
|
import 'DebugHelper.dart';
|
||||||
|
|
||||||
class Backend{
|
class Backend {
|
||||||
static const String API_ENDPOINT = "https://vps.playpoolstudios.com/metahunt/api/launcher/";
|
static const String API_ENDPOINT = "https://vps.playpoolstudios.com/metahunt/api/launcher/";
|
||||||
|
static const String SOLOGIN_ENDPOINT = "http://vps.playpoolstudios.com:20017/";
|
||||||
|
|
||||||
static List<GameData> Games = [
|
static List<GameData> Games = [
|
||||||
GameData(0,"mhunt","Metahunt", "High-Stake Battle Royale game with Play to earn abilities", "images/mhunt_thumbnail.png", true,"METAHUNT.exe"),
|
GameData(0, "mhunt", "Metahunt", "High-Stake Battle Royale game with Play to earn abilities", "images/mhunt_thumbnail.png", true, "METAHUNT.exe"),
|
||||||
GameData(1,"pop3d","Pop3D", "a game I dont know much about xD", "images/pop3d_thumbnail.png", false, "pop3d.exe"),
|
GameData(1, "pop3d", "Pop3D", "a game I dont know much about xD", "images/pop3d_thumbnail.png", false, "pop3d.exe"),
|
||||||
];
|
];
|
||||||
static SharedPreferences? prefs;
|
static SharedPreferences? prefs;
|
||||||
static Directory? docPath;
|
static Directory? docPath;
|
||||||
|
|
||||||
static String Username="";
|
static String Username = "";
|
||||||
static String displayName = "";
|
static String displayName = "";
|
||||||
|
static String walletAddress = "";
|
||||||
|
static String pubKey = "";
|
||||||
|
|
||||||
static Map<String,dynamic> UserJson = {'username':'test', 'passwd':'test123'};
|
static Map<String, dynamic> UserJson = {'username': 'test', 'passwd': 'test123'};
|
||||||
|
|
||||||
static Future<bool> Login(String username, String password) async{
|
static Future<bool> Login(String username, String password) async {
|
||||||
var loginResponse = null;
|
var loginResponse = null;
|
||||||
init();
|
init();
|
||||||
try {
|
try {
|
||||||
loginResponse = (await http.post(Uri.parse('${API_ENDPOINT}login.php'),
|
loginResponse = (await http.post(Uri.parse('${API_ENDPOINT}login.php'), body: <String, String>{"username": username, "password": password}));
|
||||||
body: <String, String>{"username": username, "password": password}));
|
Debug.LogResponse(loginResponse.body.toString(), src: '${API_ENDPOINT}login.php');
|
||||||
Debug.LogResponse(loginResponse.body.toString(),src: '${API_ENDPOINT}login.php');
|
|
||||||
|
|
||||||
|
if(loginResponse.body.toString().contains("no user")){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
Username=username;
|
Username = username;
|
||||||
SetUsernamePassword(username, password);
|
SetUsernamePassword(username, password);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {}
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Debug.LogError("Error while login $e");
|
Debug.LogError("Error while login $e");
|
||||||
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void init()async{
|
static void init() async {
|
||||||
prefs = await SharedPreferences.getInstance();
|
prefs = await SharedPreferences.getInstance();
|
||||||
docPath = await getDownloadsDirectory();
|
docPath = await getDownloadsDirectory();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<bool> Register(String username, String password, String displayname) async{
|
static Future<bool> Register(String username, String password, String displayname) async {
|
||||||
var loginResponse = null;
|
var loginResponse = null;
|
||||||
init();
|
init();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
loginResponse = (await http.post(Uri.parse('${API_ENDPOINT}register.php'),
|
loginResponse = (await http.post(Uri.parse('${API_ENDPOINT}register.php'), body: <String, String>{"username": username, "password": password, "display_name": displayname}));
|
||||||
body: <String, String>{"username": username, "password": password, "display_name": displayname}));
|
Debug.LogResponse(loginResponse.body.toString(), src: '${API_ENDPOINT}register.php');
|
||||||
Debug.LogResponse(loginResponse.body.toString(),src: '${API_ENDPOINT}register.php');
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
SetUsernamePassword(username, password);
|
SetUsernamePassword(username, password);
|
||||||
Username = username;
|
Username = username;
|
||||||
displayName=displayname;
|
Debug.Log("User is " + username);
|
||||||
|
displayName = displayname;
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {}
|
||||||
}
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Debug.LogError("Error while login $e");
|
Debug.LogError("Error while login $e");
|
||||||
}
|
}
|
||||||
|
|
@ -71,44 +77,49 @@ class Backend{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetUsernamePassword(String username, String passwd){
|
static Future<String> GetPubkey() async{
|
||||||
UserJson = {'username':username, 'passwd':passwd};
|
var response = await http.get(Uri.parse('${SOLOGIN_ENDPOINT}getPubkey?email=${Username}'));
|
||||||
|
pubKey = jsonDecode(response.body.toString())["pub_key"];
|
||||||
|
return pubKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<LeaderboardEntry>> GetLeaderboard(String gameCode) async{
|
static void SetUsernamePassword(String username, String passwd) {
|
||||||
|
UserJson = {'username': username, 'passwd': passwd};
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<List<LeaderboardEntry>> GetLeaderboard(String gameCode) async {
|
||||||
String url = '${API_ENDPOINT}/${gameCode}/get_leaderboard.php';
|
String url = '${API_ENDPOINT}/${gameCode}/get_leaderboard.php';
|
||||||
var leaderboardResponse = await http.get(Uri.parse(url));
|
var leaderboardResponse = await http.get(Uri.parse(url));
|
||||||
|
|
||||||
return LeaderboardEntry.listFromJson(leaderboardResponse.body);
|
return LeaderboardEntry.listFromJson(leaderboardResponse.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<List<Map<String,dynamic>>> GetNewsForGame(int gameId)async{
|
static Future<List<Map<String, dynamic>>> GetNewsForGame(int gameId) async {
|
||||||
String url = '${API_ENDPOINT}${Games[gameId].code}/get_news.php';
|
String url = '${API_ENDPOINT}${Games[gameId].code}/get_news.php';
|
||||||
try{
|
try {
|
||||||
var res = await http.get(Uri.parse(url));
|
var res = await http.get(Uri.parse(url));
|
||||||
List<dynamic> jsonList = jsonDecode(res.body);
|
List<dynamic> jsonList = jsonDecode(res.body);
|
||||||
List<Map<String,dynamic>> output = [];
|
List<Map<String, dynamic>> output = [];
|
||||||
jsonList.forEach((element) {
|
jsonList.forEach((element) {
|
||||||
output.add(element as Map<String,dynamic>);
|
output.add(element as Map<String, dynamic>);
|
||||||
});
|
});
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}catch(e){
|
} catch (e) {
|
||||||
Debug.LogError(e);
|
Debug.LogError(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [{}];
|
return [{}];
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<Map<String,dynamic>> GetUserStatsForGame(int gameId) async{
|
static Future<Map<String, dynamic>> GetUserStatsForGame(int gameId) async {
|
||||||
var loginResponse = null;
|
var loginResponse = null;
|
||||||
init();
|
init();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String url = '${API_ENDPOINT}${Games[gameId].code}/get_user_stats.php';
|
String url = '${API_ENDPOINT}${Games[gameId].code}/get_user_stats.php';
|
||||||
loginResponse = (await http.post(Uri.parse(url),
|
loginResponse = (await http.post(Uri.parse(url), body: <String, String>{"username": Username ?? "test"}));
|
||||||
body: <String, String>{"username": prefs!.getString("username") ?? "test"}));
|
Debug.LogResponse(loginResponse.body.toString(), src: url);
|
||||||
Debug.LogResponse(loginResponse.body.toString(),src: url);
|
|
||||||
|
|
||||||
return jsonDecode(loginResponse.body);
|
return jsonDecode(loginResponse.body);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -118,13 +129,13 @@ class Backend{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<String> CreateRequest() async{
|
static Future<String> CreateRequest() async {
|
||||||
var loginResponse = null;
|
var loginResponse = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String url = '${API_ENDPOINT}create_request.php';
|
String url = '${API_ENDPOINT}create_request.php';
|
||||||
loginResponse = await http.get(Uri.parse(url));
|
loginResponse = await http.get(Uri.parse(url));
|
||||||
Debug.LogResponse(loginResponse.body.toString(),src: url);
|
Debug.LogResponse(loginResponse.body.toString(), src: url);
|
||||||
|
|
||||||
return loginResponse.body.toString();
|
return loginResponse.body.toString();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -134,14 +145,13 @@ class Backend{
|
||||||
return "-1";
|
return "-1";
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<String> GetRequestResponse(String id) async{
|
static Future<String> GetRequestResponse(String id) async {
|
||||||
var loginResponse = null;
|
var loginResponse = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String url = '${API_ENDPOINT}get_request_response.php';
|
String url = '${API_ENDPOINT}get_request_response.php';
|
||||||
loginResponse = (await http.post(Uri.parse(url),
|
loginResponse = (await http.post(Uri.parse(url), body: <String, String>{"id": id.toString()}));
|
||||||
body: <String, String>{"id":id.toString()}));
|
Debug.LogResponse(loginResponse.body.toString(), src: url);
|
||||||
Debug.LogResponse(loginResponse.body.toString(),src: url);
|
|
||||||
|
|
||||||
return loginResponse.body;
|
return loginResponse.body;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -151,14 +161,13 @@ class Backend{
|
||||||
return "-1";
|
return "-1";
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<String> GetDisplayName(String id) async{
|
static Future<String> GetDisplayName(String id) async {
|
||||||
var response = null;
|
var response = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String url = '${API_ENDPOINT}get_display_name.php';
|
String url = '${API_ENDPOINT}get_display_name.php';
|
||||||
response = (await http.post(Uri.parse(url),
|
response = (await http.post(Uri.parse(url), body: <String, String>{"id": id.toString()}));
|
||||||
body: <String, String>{"id":id.toString()}));
|
Debug.LogResponse(response.body.toString(), src: url);
|
||||||
Debug.LogResponse(response.body.toString(),src: url);
|
|
||||||
|
|
||||||
return response.body;
|
return response.body;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -168,18 +177,17 @@ class Backend{
|
||||||
return "-1";
|
return "-1";
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<bool> GetUsernameValidation(String username) async{
|
static Future<bool> GetUsernameValidation(String username) async {
|
||||||
var loginResponse = null;
|
var loginResponse = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String url = '${API_ENDPOINT}validate_username.php';
|
String url = '${API_ENDPOINT}validate_username.php';
|
||||||
loginResponse = (await http.post(Uri.parse(url),
|
loginResponse = (await http.post(Uri.parse(url), body: <String, String>{"username": username}));
|
||||||
body: <String, String>{"username":username}));
|
Debug.LogResponse(loginResponse.body.toString(), src: url);
|
||||||
Debug.LogResponse(loginResponse.body.toString(),src: url);
|
|
||||||
|
|
||||||
if(loginResponse.body == "0"){
|
if (loginResponse.body == "0") {
|
||||||
return true;
|
return true;
|
||||||
}else{
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -188,10 +196,39 @@ class Backend{
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<String> GetNextGuestUsername() async{
|
||||||
|
try{
|
||||||
|
String url = '${API_ENDPOINT}get_next_guest_username.php';
|
||||||
|
var response = await http.get(Uri.parse(url));
|
||||||
|
|
||||||
|
return response.body.toString();
|
||||||
|
}catch(e){
|
||||||
|
|
||||||
|
}
|
||||||
|
Random random = new Random();
|
||||||
|
return 'guest ${random.nextInt(10000000)}';
|
||||||
|
}
|
||||||
|
|
||||||
|
static VaultData vault = VaultData('0x0', 0, 0);
|
||||||
|
|
||||||
|
static Future<VaultData> RefreshVaultData() async{
|
||||||
|
var response = null;
|
||||||
|
try{
|
||||||
|
String url = '${API_ENDPOINT}get_vault_data.php';
|
||||||
|
response = (await http.post(Uri.parse(url), body: <String,String>{"id": Username}));
|
||||||
|
Debug.LogResponse(response.body.toString(), src:url);
|
||||||
|
|
||||||
|
vault = jsonDecode(response.body.toString());
|
||||||
|
}catch(e){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return vault;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GameData {
|
||||||
class GameData{
|
|
||||||
int id;
|
int id;
|
||||||
String code;
|
String code;
|
||||||
String name;
|
String name;
|
||||||
|
|
@ -200,5 +237,13 @@ class GameData{
|
||||||
bool isAvailable;
|
bool isAvailable;
|
||||||
String exeName;
|
String exeName;
|
||||||
|
|
||||||
GameData(this.id,this.code,this.name,this.description,this.imagePath,this.isAvailable,this.exeName);
|
GameData(this.id, this.code, this.name, this.description, this.imagePath, this.isAvailable, this.exeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
class VaultData{
|
||||||
|
String address;
|
||||||
|
int vc;
|
||||||
|
int php;
|
||||||
|
|
||||||
|
VaultData(this.address, this.vc, this.php);
|
||||||
}
|
}
|
||||||
|
|
@ -35,14 +35,16 @@ class InstallHelper{
|
||||||
localFiles = await getHashtable(pathDir);
|
localFiles = await getHashtable(pathDir);
|
||||||
}
|
}
|
||||||
//Get local hashtable
|
//Get local hashtable
|
||||||
// Debug.Log(localFilesJson);
|
Debug.LogResponse(jsonEncode(localFiles), src:"local files");
|
||||||
//Write to file
|
//Write to file
|
||||||
if(!usedLocalSave){
|
if(!usedLocalSave){
|
||||||
String localFilesJson = FileHashEntry.listToJson(localFiles);
|
String localFilesJson = FileHashEntry.listToJson(localFiles);
|
||||||
Backend.prefs!.setString(GetValidationSaveKey(gameId),localFilesJson);
|
Backend.prefs!.setString(GetValidationSaveKey(gameId),localFilesJson);
|
||||||
if(kDebugMode) {
|
if(kDebugMode) {
|
||||||
File writeJsonFile = File(Path.join(pathDir.parent.path, "hashes.txt"));
|
String hashFilePath = Path.join(pathDir.parent.path, "hashes.txt");
|
||||||
|
File writeJsonFile = File(hashFilePath);
|
||||||
writeJsonFile.writeAsString(localFilesJson);
|
writeJsonFile.writeAsString(localFilesJson);
|
||||||
|
Debug.Log("Wrote hash into ${hashFilePath}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
39
lib/Shared/Dialogs.dart
Normal file
39
lib/Shared/Dialogs.dart
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||||
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
|
import '../main.dart';
|
||||||
|
|
||||||
|
class Dialogs{
|
||||||
|
|
||||||
|
static showAlertDialog(BuildContext context, String title, String message) {
|
||||||
|
// set up the button
|
||||||
|
Widget okButton = TextButton(
|
||||||
|
child: Text("OK"),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
// set up the AlertDialog
|
||||||
|
AlertDialog alert = AlertDialog(
|
||||||
|
backgroundColor: Color(0xFF1F1F1F),
|
||||||
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
||||||
|
title: Text(title),
|
||||||
|
content: Text(message),
|
||||||
|
actions: [
|
||||||
|
okButton,
|
||||||
|
],
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
// show the dialog
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return alert;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
75
lib/Widgets/Home/AccountsPage.dart
Normal file
75
lib/Widgets/Home/AccountsPage.dart
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
|
|
||||||
|
import '../../Backend/Backend.dart';
|
||||||
|
import '../CustomWidgets.dart';
|
||||||
|
|
||||||
|
Widget AccountPage(){
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(25.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text("Hello, ${Backend.displayName}", style: TextStyle(fontSize: 30)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(height: 100,),
|
||||||
|
Text(Backend.pubKey),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Text("Vault Credits",style: TextStyle(fontWeight: FontWeight.bold,fontSize: 15),),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Image.asset('images/vault.png',width: 40,height: 40,),
|
||||||
|
Text(Backend.vault.php.toString(),style: TextStyle(fontSize: 50),),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(width: 60,),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Text("Pre-hunt Points",style: TextStyle(fontWeight: FontWeight.bold,fontSize: 15),),
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Image.asset('images/token.png',width: 40,height: 40,),
|
||||||
|
Text(Backend.vault.vc.toString(),style: TextStyle(fontSize: 50),),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
// Text("Your wallet address is "),
|
||||||
|
// Row(
|
||||||
|
// mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
// children: [
|
||||||
|
// Text(Backend.walletAddress, style: TextStyle(fontSize: 25),),
|
||||||
|
// InkWell(child: Padding(
|
||||||
|
// padding: const EdgeInsets.all(16.0),
|
||||||
|
// child: Icon(Icons.copy),
|
||||||
|
// ), onTap: (){
|
||||||
|
// //Copy wallet
|
||||||
|
// },)
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
SizedBox(height: 50,),
|
||||||
|
GlassButton(onTap: (){
|
||||||
|
launchUrlString('https://auth.playpoolstudios.com');
|
||||||
|
}, child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text("Open Dashboard"),
|
||||||
|
SizedBox(width: 10,),
|
||||||
|
Icon(Icons.open_in_new, color: Colors.grey)
|
||||||
|
],
|
||||||
|
), width: 250, height: 50)
|
||||||
|
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
342
lib/Widgets/Home/Dashboard.dart
Normal file
342
lib/Widgets/Home/Dashboard.dart
Normal file
|
|
@ -0,0 +1,342 @@
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:filepicker_windows/filepicker_windows.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../Backend/Backend.dart';
|
||||||
|
import '../../Backend/FileHashEntry.dart';
|
||||||
|
import '../../Backend/InstallHelper.dart';
|
||||||
|
import '../../Backend/Structures.dart';
|
||||||
|
import '../CustomWidgets.dart';
|
||||||
|
|
||||||
|
Widget Dashboard({
|
||||||
|
required BuildContext context,
|
||||||
|
required Map<int, List<FileHashEntry>> downloadQueue,
|
||||||
|
required int dashboardSelectedGameIndex,
|
||||||
|
required List<FileHashEntry> missingFilesForSelectedGame,
|
||||||
|
required bool calculatingFiles,
|
||||||
|
required bool isUninstalling,
|
||||||
|
required bool isRunning,
|
||||||
|
required Map<String, dynamic> myStatsForSelectedGame,
|
||||||
|
required List<LeaderboardEntry> leaderboardForSelectedGame,
|
||||||
|
required List<Map<String, dynamic>> newsForSelectedGame,
|
||||||
|
|
||||||
|
required Function(int) onSelectedGameChanged,
|
||||||
|
required Function onUpdate,
|
||||||
|
required Function(int) onUninstallClicked,
|
||||||
|
required dynamic OnGameActionButtonClicked,
|
||||||
|
|
||||||
|
}) {
|
||||||
|
GameData selectedGameData = Backend.Games[dashboardSelectedGameIndex];
|
||||||
|
String filePath = InstallHelper.GetFilePath(dashboardSelectedGameIndex);
|
||||||
|
bool folderExists = Directory(filePath).existsSync();
|
||||||
|
String ActionBtnTxt = "Install";
|
||||||
|
|
||||||
|
if (missingFilesForSelectedGame.length <= 0) {
|
||||||
|
ActionBtnTxt = "Play";
|
||||||
|
} else {
|
||||||
|
ActionBtnTxt =
|
||||||
|
("Download ${FileHashEntry.getTotalSizeInMbytes(missingFilesForSelectedGame).toStringAsFixed(0)} MB");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (calculatingFiles) {
|
||||||
|
ActionBtnTxt = "Validating";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (downloadQueue.containsKey(dashboardSelectedGameIndex)) {
|
||||||
|
ActionBtnTxt = "Downloading";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isUninstalling) {
|
||||||
|
ActionBtnTxt = "Uninstalling";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isRunning){
|
||||||
|
ActionBtnTxt = "Running";
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget ActionButton = GlassButton(
|
||||||
|
onTap: OnGameActionButtonClicked,
|
||||||
|
child: Text(ActionBtnTxt),
|
||||||
|
width: 200,
|
||||||
|
color: Colors.blue,
|
||||||
|
opacity: 0.5,
|
||||||
|
height: 50);
|
||||||
|
|
||||||
|
final screenHeight = MediaQuery.of(context).size.height;
|
||||||
|
List<DataRow> leaderboardList = [];
|
||||||
|
// leaderboardList.add(TableRow(children: [Text("username"),Text("kills"), Text("deaths")]));
|
||||||
|
// leaderboardList.add(TableRow());
|
||||||
|
leaderboardList
|
||||||
|
.addAll(List.generate(leaderboardForSelectedGame.length, (i) {
|
||||||
|
return DataRow(cells: <DataCell>[
|
||||||
|
DataCell(Text(leaderboardForSelectedGame[i].place.toString())),
|
||||||
|
DataCell(Text(leaderboardForSelectedGame[i].username)),
|
||||||
|
DataCell(Text(leaderboardForSelectedGame[i].kills.toString())),
|
||||||
|
DataCell(Text(leaderboardForSelectedGame[i].deaths.toString())),
|
||||||
|
DataCell(Text(leaderboardForSelectedGame[i].xp.toString())),
|
||||||
|
]);
|
||||||
|
}));
|
||||||
|
|
||||||
|
return Theme(
|
||||||
|
data: ThemeData(splashColor: Colors.transparent),
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: screenHeight * 0.18,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
selectedGameData.name,
|
||||||
|
style: TextStyle(fontSize: 25),
|
||||||
|
),
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: List.generate(Backend.Games.length, (index) {
|
||||||
|
bool isSelected = index == dashboardSelectedGameIndex;
|
||||||
|
return InkWell(
|
||||||
|
onTap: (){
|
||||||
|
onSelectedGameChanged(index);
|
||||||
|
},
|
||||||
|
child: AnimatedContainer(
|
||||||
|
duration: const Duration(milliseconds: 100),
|
||||||
|
margin: EdgeInsets.all(9),
|
||||||
|
height: 80 * (isSelected ? 1.5 : 1),
|
||||||
|
width: 130 * (isSelected ? 1.5 : 1),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image:
|
||||||
|
AssetImage(Backend.Games[index].imagePath),
|
||||||
|
fit: BoxFit.fill),
|
||||||
|
borderRadius: BorderRadius.circular(20)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
!Backend.Games[dashboardSelectedGameIndex].isAvailable
|
||||||
|
? Center(
|
||||||
|
child: Text("Coming Soon", style: TextStyle(fontSize: 40)))
|
||||||
|
: Container(
|
||||||
|
height: screenHeight * 0.72,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 50),
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
ActionButton,
|
||||||
|
PopupMenuButton<String>(
|
||||||
|
iconColor: Colors.blueGrey,
|
||||||
|
onSelected: (val) {
|
||||||
|
if (val.toLowerCase().contains("uninstall")) {
|
||||||
|
onUninstallClicked(dashboardSelectedGameIndex);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
itemBuilder: (BuildContext context) {
|
||||||
|
return {'Uninstall'}.map((String choice) {
|
||||||
|
return PopupMenuItem<String>(
|
||||||
|
value: choice,
|
||||||
|
child: Text(choice),
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
|
||||||
|
],
|
||||||
|
),
|
||||||
|
GlassCard(
|
||||||
|
color: Colors.green,
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Text("My Stats",
|
||||||
|
style:
|
||||||
|
TextStyle(color: Colors.blueGrey)),
|
||||||
|
SizedBox(
|
||||||
|
width: 50,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Text(
|
||||||
|
"Kills : ${(myStatsForSelectedGame['kills'] ?? "0")}"),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Text(
|
||||||
|
"Deaths : ${(myStatsForSelectedGame['deaths'] ?? "0")}"),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Text(
|
||||||
|
"Assist : ${(myStatsForSelectedGame['assists'] ?? "0")}"),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
height: screenHeight * 0.6,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
|
||||||
|
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(20.0),
|
||||||
|
child: GlassCard(
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
width: 350,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
vertical: 12.0, horizontal: 20),
|
||||||
|
child: Text(
|
||||||
|
"News",
|
||||||
|
style: TextStyle(fontSize: 20),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
child: Column(
|
||||||
|
children: List.generate(
|
||||||
|
newsForSelectedGame.length,
|
||||||
|
(index) {
|
||||||
|
return NewsCard(
|
||||||
|
newsForSelectedGame[index]
|
||||||
|
['title'],
|
||||||
|
newsForSelectedGame[index]
|
||||||
|
['message']);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
width: 50,
|
||||||
|
),
|
||||||
|
SingleChildScrollView(
|
||||||
|
scrollDirection: Axis.vertical,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(
|
||||||
|
0, 20, 0, 0),
|
||||||
|
child: Text(
|
||||||
|
"Leaderboard",
|
||||||
|
style: TextStyle(fontSize: 20),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
DataTable(
|
||||||
|
dataTextStyle:
|
||||||
|
TextStyle(color: Colors.white),
|
||||||
|
headingTextStyle:
|
||||||
|
TextStyle(color: Colors.white),
|
||||||
|
dividerThickness: 0,
|
||||||
|
columns: [
|
||||||
|
DataColumn(
|
||||||
|
label:
|
||||||
|
Expanded(child: Text("Place"))),
|
||||||
|
DataColumn(
|
||||||
|
label: Expanded(
|
||||||
|
child: Text("Username"))),
|
||||||
|
DataColumn(
|
||||||
|
label:
|
||||||
|
Expanded(child: Text("Kills"))),
|
||||||
|
DataColumn(
|
||||||
|
label: Expanded(
|
||||||
|
child: Text("Deaths"))),
|
||||||
|
DataColumn(
|
||||||
|
label: Expanded(child: Text("XP"))),
|
||||||
|
],
|
||||||
|
rows: leaderboardList,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
//Install path footer
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10),
|
||||||
|
alignment: Alignment.bottomCenter,
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(children: [Text("Install path "), Text(filePath)]),
|
||||||
|
GlassButton(
|
||||||
|
onTap: () {
|
||||||
|
DirectoryPicker file = DirectoryPicker();
|
||||||
|
final dir = file.getDirectory();
|
||||||
|
Backend.prefs!.setString(
|
||||||
|
'${selectedGameData.name}_path', dir!.path);
|
||||||
|
onUpdate();
|
||||||
|
},
|
||||||
|
child: Text("Change Install Location"),
|
||||||
|
width: 250)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 10,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget NewsCard(String title, String message) {
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(5.0),
|
||||||
|
child: GlassCard(
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.all(18.0),
|
||||||
|
child: Icon(
|
||||||
|
Icons.newspaper,
|
||||||
|
color: Colors.blueGrey,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: TextStyle(fontSize: 18),
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
message,
|
||||||
|
overflow: TextOverflow.clip,
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
129
lib/Widgets/Home/Downloads.dart
Normal file
129
lib/Widgets/Home/Downloads.dart
Normal file
|
|
@ -0,0 +1,129 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../Backend/Backend.dart';
|
||||||
|
import '../../Backend/FileHashEntry.dart';
|
||||||
|
import '../CustomWidgets.dart';
|
||||||
|
|
||||||
|
Widget DownloadCard({
|
||||||
|
required int gameId,
|
||||||
|
required Map<int, Map<FileHashEntry, num>> downloadProgress,
|
||||||
|
required Map<int, double> totalDownloadSize,
|
||||||
|
required Map<int, List<FileHashEntry>> downloadQueue,
|
||||||
|
required bool downloadRunning,
|
||||||
|
required Function(int) onChanged
|
||||||
|
}) {
|
||||||
|
int doneSize = 0;
|
||||||
|
if (downloadProgress.containsKey(gameId)) {
|
||||||
|
Map<FileHashEntry, num> _progress = downloadProgress[gameId]!;
|
||||||
|
_progress.forEach((key, value) {
|
||||||
|
doneSize += value.toInt();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
double totalSize = totalDownloadSize[gameId]! / 1024 / 1024;
|
||||||
|
double doneSizeMb = doneSize / 1024 / 1024;
|
||||||
|
double progress = doneSizeMb / totalSize;
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: GlassCard(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
image: DecorationImage(
|
||||||
|
image:
|
||||||
|
AssetImage(Backend.Games[gameId].imagePath)),
|
||||||
|
borderRadius: BorderRadius.circular(50)),
|
||||||
|
width: 160,
|
||||||
|
height: 80,
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
Backend.Games[gameId].name,
|
||||||
|
style: TextStyle(fontSize: 20),
|
||||||
|
),
|
||||||
|
Text((doneSizeMb).toStringAsFixed(2) +
|
||||||
|
" MB" +
|
||||||
|
" / " +
|
||||||
|
totalSize.toStringAsFixed(2) +
|
||||||
|
" MB")
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Expanded(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(20, 50, 20, 20),
|
||||||
|
child: LinearProgressIndicator(
|
||||||
|
value: progress,
|
||||||
|
backgroundColor: Colors.black.withOpacity(0.2),
|
||||||
|
color: Colors.blue,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
child: Icon(Icons.cancel,
|
||||||
|
size: 40, color: Colors.red.withOpacity(0.6)),
|
||||||
|
onTap: () {
|
||||||
|
downloadQueue.remove(gameId);
|
||||||
|
downloadProgress.remove(gameId);
|
||||||
|
downloadRunning = false;
|
||||||
|
onChanged(gameId);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
// Icon(Icons.download,size: 40,color: Colors.green.withOpacity(0.4),)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget Downloads({
|
||||||
|
required Map<int, List<FileHashEntry>> downloadQueue,
|
||||||
|
required Map<int, Map<FileHashEntry, num>> downloadProgress,
|
||||||
|
required Map<int, double> totalDownloadSize,
|
||||||
|
required bool downloadRunning,
|
||||||
|
required Function(int) onChanged
|
||||||
|
}) {
|
||||||
|
if (downloadQueue.length <= 0) {
|
||||||
|
return Center(
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(
|
||||||
|
Icons.download_done_sharp,
|
||||||
|
size: 100,
|
||||||
|
color: Colors.white.withOpacity(0.5),
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
"No ongoing Downloads",
|
||||||
|
style:
|
||||||
|
TextStyle(fontSize: 40, color: Colors.white.withOpacity(0.4)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
child: Container(
|
||||||
|
padding: EdgeInsets.all(100),
|
||||||
|
child: GlassCard(
|
||||||
|
child: Column(
|
||||||
|
children: List.generate(downloadQueue.keys.length, (index) {
|
||||||
|
int gameId = downloadQueue.keys.toList()[index];
|
||||||
|
return DownloadCard(gameId: gameId, downloadQueue:downloadQueue, downloadProgress: downloadProgress, downloadRunning: downloadRunning, totalDownloadSize: totalDownloadSize, onChanged: onChanged );
|
||||||
|
}),
|
||||||
|
))));
|
||||||
|
}
|
||||||
98
lib/Widgets/Home/Library.dart
Normal file
98
lib/Widgets/Home/Library.dart
Normal file
|
|
@ -0,0 +1,98 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../Backend/Backend.dart';
|
||||||
|
import '../CustomWidgets.dart';
|
||||||
|
|
||||||
|
String hoveringGameCard = "";
|
||||||
|
|
||||||
|
Widget Library({
|
||||||
|
required int selectedSidebarIndex,
|
||||||
|
|
||||||
|
required Function(int) onGameChanged,
|
||||||
|
required Function onUpdate,
|
||||||
|
}) {
|
||||||
|
return Center(
|
||||||
|
child: Wrap(
|
||||||
|
spacing: 20,
|
||||||
|
children: List.generate(Backend.Games.length, (index) {
|
||||||
|
GameData gameData = Backend.Games[index];
|
||||||
|
return LibGameCard(
|
||||||
|
gameData: gameData,
|
||||||
|
selectedSidebarIndex: selectedSidebarIndex,
|
||||||
|
onUpdate: onUpdate,
|
||||||
|
onGameChanged: onGameChanged
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget LibGameCard({
|
||||||
|
required GameData gameData,
|
||||||
|
required int selectedSidebarIndex,
|
||||||
|
|
||||||
|
required Function(int) onGameChanged,
|
||||||
|
required Function onUpdate,
|
||||||
|
}) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
selectedSidebarIndex = 1;
|
||||||
|
onGameChanged(gameData.id);
|
||||||
|
},
|
||||||
|
onHover: (val) {
|
||||||
|
if (val) {
|
||||||
|
hoveringGameCard = gameData.name;
|
||||||
|
} else if (hoveringGameCard == gameData.name) {
|
||||||
|
hoveringGameCard = "";
|
||||||
|
}
|
||||||
|
onUpdate();
|
||||||
|
},
|
||||||
|
child: AnimatedContainer(
|
||||||
|
duration: const Duration(milliseconds: 500),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(20),
|
||||||
|
color: Colors.black,
|
||||||
|
image: DecorationImage(
|
||||||
|
image: AssetImage(gameData.imagePath), fit: BoxFit.fill)),
|
||||||
|
height: 200,
|
||||||
|
width: 300,
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
hoveringGameCard != gameData.name
|
||||||
|
? Container()
|
||||||
|
: Expanded(
|
||||||
|
child: GlassContainer(
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
gameData.description,
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
opacity: 0.5,
|
||||||
|
color: Colors.black)),
|
||||||
|
GlassContainer(
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.all(8.0),
|
||||||
|
child: true? Container():Row(
|
||||||
|
children: [
|
||||||
|
Text(gameData.name),
|
||||||
|
gameData.isAvailable
|
||||||
|
? GlassButton(
|
||||||
|
onTap: () {},
|
||||||
|
child: Text("Install"),
|
||||||
|
width: 100,
|
||||||
|
color: Colors.blue,
|
||||||
|
opacity: 0.8)
|
||||||
|
: Text("Coming soon")
|
||||||
|
],
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
opacity: 0.9,
|
||||||
|
color: Colors.black),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
127
lib/Widgets/Home/Sidebar.dart
Normal file
127
lib/Widgets/Home/Sidebar.dart
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../Backend/Backend.dart';
|
||||||
|
import '../CustomWidgets.dart';
|
||||||
|
|
||||||
|
|
||||||
|
int selectedSidebarIndex = 0;
|
||||||
|
|
||||||
|
Widget SideBar(
|
||||||
|
{required double width, required double height,required Function(int) onChanged, int selectedIndex = 0}) {
|
||||||
|
return GlassContainer(
|
||||||
|
child: Container(
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
child: Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
|
||||||
|
SizedBox(
|
||||||
|
height: 100,
|
||||||
|
),
|
||||||
|
SidebarTitle("Library", Icons.laptop_chromebook_outlined, onChanged,
|
||||||
|
index: 0),
|
||||||
|
SidebarTitle("Dashboard", Icons.dashboard,onChanged, index: 1),
|
||||||
|
SidebarTitle("Downloads", Icons.download,onChanged, index: 2),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
InkWell(
|
||||||
|
onTap:(){
|
||||||
|
selectedSidebarIndex=3;
|
||||||
|
onChanged(3);
|
||||||
|
},
|
||||||
|
child: GlassContainer(child: Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(10,0,10,10),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Icon(Icons.supervised_user_circle_rounded, size: 50),
|
||||||
|
SizedBox(width: 15,),
|
||||||
|
Column(crossAxisAlignment:CrossAxisAlignment.start,children: [
|
||||||
|
Text(Backend.displayName,style: TextStyle(fontSize: 24),),
|
||||||
|
// Text("Vault credits : 50")
|
||||||
|
Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10,vertical: 2),
|
||||||
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.black.withAlpha(100)),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 30,
|
||||||
|
width: 30,
|
||||||
|
child: Image.asset('images/vault.png'),
|
||||||
|
),
|
||||||
|
SizedBox(width: 5,),
|
||||||
|
Text(Backend.vault.vc.toString())
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(width: 5,),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10,vertical: 2),
|
||||||
|
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10), color: Colors.black.withAlpha(100)),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
height: 30,
|
||||||
|
width: 30,
|
||||||
|
child: Image.asset('images/token.png'),
|
||||||
|
),
|
||||||
|
SizedBox(width: 5,),
|
||||||
|
Text(Backend.vault.php.toString())
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
opacity: 0.15,
|
||||||
|
color: Colors.blueGrey);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget SidebarTitle(String title, IconData iconData, Function(int) onChanged, {int index = 0}) {
|
||||||
|
return InkWell(
|
||||||
|
onTap: () {
|
||||||
|
selectedSidebarIndex = index;
|
||||||
|
onChanged(index);
|
||||||
|
},
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 0),
|
||||||
|
child: GlassContainer(
|
||||||
|
opacity: selectedSidebarIndex == index ? 0.1 : 0,
|
||||||
|
color:
|
||||||
|
selectedSidebarIndex == index ? Colors.white : Colors.transparent,
|
||||||
|
child: Container(
|
||||||
|
height: 75,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(iconData),
|
||||||
|
SizedBox(
|
||||||
|
width: 20,
|
||||||
|
),
|
||||||
|
Text(
|
||||||
|
title,
|
||||||
|
style: TextStyle(fontSize: 20),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:mhunt_launcher/home.dart';
|
import 'package:mhunt_launcher/home.dart';
|
||||||
import 'package:process_run/shell.dart';
|
import 'package:mhunt_launcher/login.dart';
|
||||||
|
|
||||||
class UpdateCheckScreen extends StatefulWidget {
|
class UpdateCheckScreen extends StatefulWidget {
|
||||||
const UpdateCheckScreen({super.key});
|
const UpdateCheckScreen({super.key});
|
||||||
|
|
@ -15,8 +16,8 @@ class UpdateCheckScreen extends StatefulWidget {
|
||||||
|
|
||||||
class _UpdateCheckScreenState extends State<UpdateCheckScreen> {
|
class _UpdateCheckScreenState extends State<UpdateCheckScreen> {
|
||||||
|
|
||||||
int localVersion = 0;
|
int localVersion = 4;
|
||||||
String otaPath = Directory.current.path + "\\ota_wrapper_v2.exe";
|
String otaPath = Directory.current.path + "\\ota_wrapper_silent.vbs";
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
|
@ -25,31 +26,35 @@ class _UpdateCheckScreenState extends State<UpdateCheckScreen> {
|
||||||
|
|
||||||
CheckForUpdates();
|
CheckForUpdates();
|
||||||
}
|
}
|
||||||
Future<List<ProcessResult>> runExecutable(String executable) async {
|
|
||||||
return await run(executable);
|
|
||||||
}
|
|
||||||
void CheckForUpdates() async{
|
void CheckForUpdates() async{
|
||||||
// http.Response remoteVersionResponse = await http.get(Uri.parse("https://vps.playpoolstudios.com/metahunt/api/launcher/get_version.php"));
|
http.Response remoteVersionResponse = await http.get(Uri.parse("https://vps.playpoolstudios.com/metahunt/data/bin/launcher_win/get_version_code.php"));
|
||||||
// int remoteVersion = int.parse(remoteVersionResponse.body);
|
int remoteVersion = int.parse(remoteVersionResponse.body);
|
||||||
if(!await File(otaPath).exists()){
|
print("local version:${localVersion}, remote version:${remoteVersion}");
|
||||||
print("otapath not existing");
|
if(remoteVersion>localVersion){
|
||||||
setState(() {
|
updateStatus = 1;
|
||||||
updateStatus=2;
|
}else{
|
||||||
});
|
updateStatus=2;
|
||||||
return;
|
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context)=> LoginPage()));
|
||||||
}
|
}
|
||||||
try {
|
// if(!await File(otaPath).exists()){
|
||||||
|
// print("otapath not existing");
|
||||||
final result = await runExecutable(otaPath + " noupdate");
|
// setState(() {
|
||||||
if (result[0].stdout.trim() == '0') {
|
// updateStatus=2;
|
||||||
updateStatus = 2;
|
// });
|
||||||
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context)=> HomePage()));
|
// return;
|
||||||
}else{
|
// }
|
||||||
updateStatus = 1;
|
// try {
|
||||||
}
|
//
|
||||||
} catch (e) {
|
// final result = await runExecutable(otaPath + " noupdate");
|
||||||
print('Error running the executable: $e');
|
// if (result[0].stdout.trim() == '0') {
|
||||||
}
|
// updateStatus = 2;
|
||||||
|
// Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context)=> LoginPage()));
|
||||||
|
// }else{
|
||||||
|
// updateStatus = 1;
|
||||||
|
// }
|
||||||
|
// } catch (e) {
|
||||||
|
// print('Error running the executable: $e');
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
@ -57,10 +62,16 @@ class _UpdateCheckScreenState extends State<UpdateCheckScreen> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
void update() async{
|
void update() async{
|
||||||
await Process.start(otaPath,[], runInShell: true);
|
// await Process.start(otaPath,[], runInShell: true);
|
||||||
// await Future.delayed(const Duration(seconds: 5));
|
//
|
||||||
|
final process = await Process.start('wscript',[otaPath], runInShell: true);
|
||||||
updateStatus = 2;
|
updateStatus = 2;
|
||||||
|
process.stdout.transform(utf8.decoder).listen((data) {
|
||||||
|
});
|
||||||
|
process.stderr.transform(utf8.decoder).listen((data) {
|
||||||
|
print(data);
|
||||||
|
});
|
||||||
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
exit(0);
|
exit(0);
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
||||||
|
|
|
||||||
700
lib/home.dart
700
lib/home.dart
|
|
@ -14,11 +14,17 @@ import 'package:mhunt_launcher/sidebar.dart';
|
||||||
import 'package:process_run/process_run.dart';
|
import 'package:process_run/process_run.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:path/path.dart' as Path;
|
import 'package:path/path.dart' as Path;
|
||||||
|
import 'package:url_launcher/url_launcher_string.dart';
|
||||||
import 'Backend/DebugHelper.dart';
|
import 'Backend/DebugHelper.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
import 'Backend/FileHashEntry.dart';
|
import 'Backend/FileHashEntry.dart';
|
||||||
import 'Backend/Structures.dart';
|
import 'Backend/Structures.dart';
|
||||||
|
import 'Widgets/Home/AccountsPage.dart';
|
||||||
|
import 'Widgets/Home/Dashboard.dart';
|
||||||
|
import 'Widgets/Home/Downloads.dart';
|
||||||
|
import 'Widgets/Home/Library.dart';
|
||||||
|
import 'Widgets/Home/Sidebar.dart';
|
||||||
|
|
||||||
class HomePage extends StatefulWidget {
|
class HomePage extends StatefulWidget {
|
||||||
const HomePage({super.key});
|
const HomePage({super.key});
|
||||||
|
|
@ -39,14 +45,38 @@ class _HomePageState extends State<HomePage> {
|
||||||
bool downloadRunning = false;
|
bool downloadRunning = false;
|
||||||
int unwaitingFiles = 0;
|
int unwaitingFiles = 0;
|
||||||
int dashboardSelectedGameIndex = 0;
|
int dashboardSelectedGameIndex = 0;
|
||||||
|
String userPubKey = "loading";
|
||||||
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
// TODO: implement initState
|
// TODO: implement initState
|
||||||
super.initState();
|
super.initState();
|
||||||
kickstartAnimations();
|
kickstartAnimations();
|
||||||
|
initData();
|
||||||
|
|
||||||
SetSelectedDashboardGame(0);
|
SetSelectedDashboardGame(0);
|
||||||
|
|
||||||
|
SetVaultUpdateLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SetVaultUpdateLoop() async{
|
||||||
|
while(true){
|
||||||
|
await Backend.RefreshVaultData();
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
|
await Future.delayed(const Duration(seconds: 30));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void initData()async{
|
||||||
|
userPubKey= await Backend.GetPubkey();
|
||||||
|
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void kickstartAnimations() async {
|
void kickstartAnimations() async {
|
||||||
|
|
@ -63,11 +93,50 @@ class _HomePageState extends State<HomePage> {
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final screenHeight = MediaQuery.of(context).size.height;
|
final screenHeight = MediaQuery.of(context).size.height;
|
||||||
final screenWidth = MediaQuery.of(context).size.width;
|
final screenWidth = MediaQuery.of(context).size.width;
|
||||||
Widget content = Library();
|
Widget content = Library(
|
||||||
|
selectedSidebarIndex: selectedSidebarIndex,
|
||||||
|
onGameChanged: SetSelectedDashboardGame,
|
||||||
|
onUpdate: (){
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if (selectedSidebarIndex == 1) {
|
if (selectedSidebarIndex == 1) {
|
||||||
content = Dashboard();
|
content = Dashboard(
|
||||||
|
context: context,
|
||||||
|
downloadQueue: downloadQueue,
|
||||||
|
dashboardSelectedGameIndex: dashboardSelectedGameIndex,
|
||||||
|
missingFilesForSelectedGame: missingFilesForSelectedGame,
|
||||||
|
calculatingFiles: calculatingFiles,
|
||||||
|
isRunning: runningProcs.containsKey(dashboardSelectedGameIndex),
|
||||||
|
isUninstalling: isUninstalling,
|
||||||
|
myStatsForSelectedGame: myStatsForSelectedGame,
|
||||||
|
leaderboardForSelectedGame: leaderboardForSelectedGame,
|
||||||
|
newsForSelectedGame: newsForSelectedGame,
|
||||||
|
|
||||||
|
onSelectedGameChanged: SetSelectedDashboardGame,
|
||||||
|
onUninstallClicked: UninstallGame,
|
||||||
|
OnGameActionButtonClicked: OnGameActionButtonClicked,
|
||||||
|
onUpdate: (){
|
||||||
|
setState(() {
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
} else if (selectedSidebarIndex == 2) {
|
} else if (selectedSidebarIndex == 2) {
|
||||||
content = Downloads();
|
content = Downloads(
|
||||||
|
downloadQueue: downloadQueue,
|
||||||
|
downloadRunning: downloadRunning,
|
||||||
|
downloadProgress: downloadProgress,
|
||||||
|
totalDownloadSize: totalDownloadSize,
|
||||||
|
onChanged: (val){
|
||||||
|
setState(() {
|
||||||
|
SetSelectedDashboardGame(val);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
}else if(selectedSidebarIndex == 3){
|
}else if(selectedSidebarIndex == 3){
|
||||||
content = AccountPage();
|
content = AccountPage();
|
||||||
}
|
}
|
||||||
|
|
@ -83,7 +152,11 @@ class _HomePageState extends State<HomePage> {
|
||||||
children: [
|
children: [
|
||||||
SideBar(
|
SideBar(
|
||||||
width: screenWidth * 0.2,
|
width: screenWidth * 0.2,
|
||||||
height: screenHeight,
|
height: screenHeight, onChanged: (val){
|
||||||
|
setState(() {
|
||||||
|
selectedSidebarIndex = val;
|
||||||
|
});
|
||||||
|
},
|
||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: screenWidth * 0.8,
|
width: screenWidth * 0.8,
|
||||||
|
|
@ -96,301 +169,7 @@ class _HomePageState extends State<HomePage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget Library() {
|
|
||||||
return Center(
|
|
||||||
child: Wrap(
|
|
||||||
spacing: 20,
|
|
||||||
children: List.generate(Backend.Games.length, (index) {
|
|
||||||
GameData gameData = Backend.Games[index];
|
|
||||||
return LibGameCard(gameData);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget AccountPage(){
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.all(25.0),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text("Hello, ${Backend.displayName}", style: TextStyle(fontSize: 30)),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget Downloads() {
|
|
||||||
if (downloadQueue.length <= 0) {
|
|
||||||
return Center(
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Icon(
|
|
||||||
Icons.download_done_sharp,
|
|
||||||
size: 100,
|
|
||||||
color: Colors.white.withOpacity(0.5),
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
"No ongoing Downloads",
|
|
||||||
style:
|
|
||||||
TextStyle(fontSize: 40, color: Colors.white.withOpacity(0.4)),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Container(
|
|
||||||
child: Container(
|
|
||||||
padding: EdgeInsets.all(100),
|
|
||||||
child: GlassCard(
|
|
||||||
child: Column(
|
|
||||||
children: List.generate(downloadQueue.keys.length, (index) {
|
|
||||||
int gameId = downloadQueue.keys.toList()[index];
|
|
||||||
return DownloadCard(gameId, downloadQueue[gameId]!);
|
|
||||||
}),
|
|
||||||
))));
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget DownloadCard(int gameId, List<FileHashEntry> files) {
|
|
||||||
int doneSize = 0;
|
|
||||||
if (downloadProgress.containsKey(gameId)) {
|
|
||||||
Map<FileHashEntry, num> _progress = downloadProgress[gameId]!;
|
|
||||||
_progress.forEach((key, value) {
|
|
||||||
doneSize += value.toInt();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
double totalSize = totalDownloadSize[gameId]! / 1024 / 1024;
|
|
||||||
double doneSizeMb = doneSize / 1024 / 1024;
|
|
||||||
double progress = doneSizeMb / totalSize;
|
|
||||||
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: GlassCard(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
image: DecorationImage(
|
|
||||||
image:
|
|
||||||
AssetImage(Backend.Games[gameId].imagePath)),
|
|
||||||
borderRadius: BorderRadius.circular(50)),
|
|
||||||
width: 160,
|
|
||||||
height: 80,
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
Backend.Games[gameId].name,
|
|
||||||
style: TextStyle(fontSize: 20),
|
|
||||||
),
|
|
||||||
Text((doneSizeMb).toStringAsFixed(2) +
|
|
||||||
" MB" +
|
|
||||||
" / " +
|
|
||||||
totalSize.toStringAsFixed(2) +
|
|
||||||
" MB")
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(20, 50, 20, 20),
|
|
||||||
child: LinearProgressIndicator(
|
|
||||||
value: progress,
|
|
||||||
backgroundColor: Colors.black.withOpacity(0.2),
|
|
||||||
color: Colors.blue,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
InkWell(
|
|
||||||
child: Icon(Icons.cancel,
|
|
||||||
size: 40, color: Colors.red.withOpacity(0.6)),
|
|
||||||
onTap: () {
|
|
||||||
downloadQueue.remove(gameId);
|
|
||||||
downloadProgress.remove(gameId);
|
|
||||||
downloadRunning = false;
|
|
||||||
SetSelectedDashboardGame(gameId);
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
)
|
|
||||||
// Icon(Icons.download,size: 40,color: Colors.green.withOpacity(0.4),)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget SideBar(
|
|
||||||
{required double width, required double height, int selectedIndex = 0}) {
|
|
||||||
return GlassContainer(
|
|
||||||
child: Container(
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Column(
|
|
||||||
children: [
|
|
||||||
// Padding(
|
|
||||||
// padding: const EdgeInsets.all(8.0),
|
|
||||||
// child: Row(
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
// children: [
|
|
||||||
// SizedBox(width: 10,),
|
|
||||||
// Text("10")
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
SizedBox(
|
|
||||||
height: 100,
|
|
||||||
),
|
|
||||||
SidebarTitle("Library", Icons.laptop_chromebook_outlined,
|
|
||||||
index: 0),
|
|
||||||
SidebarTitle("Dashboard", Icons.dashboard, index: 1),
|
|
||||||
SidebarTitle("Downloads", Icons.download, index: 2),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
InkWell(
|
|
||||||
onTap:(){
|
|
||||||
setState(() {
|
|
||||||
selectedSidebarIndex=3;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
child: GlassContainer(child: Padding(
|
|
||||||
padding: const EdgeInsets.all(10.0),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Icon(Icons.supervised_user_circle_rounded, size: 50),
|
|
||||||
SizedBox(width: 15,),
|
|
||||||
Column(crossAxisAlignment:CrossAxisAlignment.start,children: [
|
|
||||||
Text(Backend.displayName,style: TextStyle(fontSize: 24),),
|
|
||||||
// Text("Vault credits : 50")
|
|
||||||
],)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
opacity: 0.15,
|
|
||||||
color: Colors.blueGrey);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget SidebarTitle(String title, IconData iconData, {int index = 0}) {
|
|
||||||
return InkWell(
|
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
selectedSidebarIndex = index;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 0),
|
|
||||||
child: GlassContainer(
|
|
||||||
opacity: selectedSidebarIndex == index ? 0.1 : 0,
|
|
||||||
color:
|
|
||||||
selectedSidebarIndex == index ? Colors.white : Colors.transparent,
|
|
||||||
child: Container(
|
|
||||||
height: 75,
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Icon(iconData),
|
|
||||||
SizedBox(
|
|
||||||
width: 20,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
title,
|
|
||||||
style: TextStyle(fontSize: 20),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
String hoveringGameCard = "";
|
|
||||||
Widget LibGameCard(GameData gameData) {
|
|
||||||
return InkWell(
|
|
||||||
onTap: () {
|
|
||||||
selectedSidebarIndex = 1;
|
|
||||||
SetSelectedDashboardGame(gameData.id);
|
|
||||||
},
|
|
||||||
onHover: (val) {
|
|
||||||
if (val) {
|
|
||||||
hoveringGameCard = gameData.name;
|
|
||||||
} else if (hoveringGameCard == gameData.name) {
|
|
||||||
hoveringGameCard = "";
|
|
||||||
}
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
child: AnimatedContainer(
|
|
||||||
duration: const Duration(milliseconds: 500),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.circular(20),
|
|
||||||
color: Colors.black,
|
|
||||||
image: DecorationImage(
|
|
||||||
image: AssetImage(gameData.imagePath), fit: BoxFit.fill)),
|
|
||||||
height: 200,
|
|
||||||
width: 300,
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
hoveringGameCard != gameData.name
|
|
||||||
? Container()
|
|
||||||
: Expanded(
|
|
||||||
child: GlassContainer(
|
|
||||||
child: Center(
|
|
||||||
child: Text(
|
|
||||||
gameData.description,
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
opacity: 0.5,
|
|
||||||
color: Colors.black)),
|
|
||||||
GlassContainer(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: true? Container():Row(
|
|
||||||
children: [
|
|
||||||
Text(gameData.name),
|
|
||||||
gameData.isAvailable
|
|
||||||
? GlassButton(
|
|
||||||
onTap: () {},
|
|
||||||
child: Text("Install"),
|
|
||||||
width: 100,
|
|
||||||
color: Colors.blue,
|
|
||||||
opacity: 0.8)
|
|
||||||
: Text("Coming soon")
|
|
||||||
],
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
opacity: 0.9,
|
|
||||||
color: Colors.black),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetSelectedDashboardGame(int i) async {
|
void SetSelectedDashboardGame(int i) async {
|
||||||
calculatingFiles = true;
|
calculatingFiles = true;
|
||||||
|
|
@ -448,7 +227,7 @@ class _HomePageState extends State<HomePage> {
|
||||||
if(runningProcs.containsKey(id)){return;}
|
if(runningProcs.containsKey(id)){return;}
|
||||||
String exePath = InstallHelper.GetExeFilePath(dashboardSelectedGameIndex);
|
String exePath = InstallHelper.GetExeFilePath(dashboardSelectedGameIndex);
|
||||||
// Process proc = await run(exePath,);
|
// Process proc = await run(exePath,);
|
||||||
runningProcs.putIfAbsent(id, ()=> run(exePath + " username ${Backend.UserJson['username']} password ${Backend.UserJson['passwd']}"));
|
runningProcs.putIfAbsent(id, ()=> run(exePath + " username ${Backend.Username} password ${Backend.UserJson['passwd']}"));
|
||||||
setState(() {
|
setState(() {
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
@ -475,11 +254,6 @@ class _HomePageState extends State<HomePage> {
|
||||||
bool isUninstalling = false;
|
bool isUninstalling = false;
|
||||||
void UninstallGame(int id) async {
|
void UninstallGame(int id) async {
|
||||||
if(runningProcs.containsKey(id)){return;}
|
if(runningProcs.containsKey(id)){return;}
|
||||||
// String exeFilePath = InstallHelper.GetExeFilePath(id);
|
|
||||||
// if(!File(exeFilePath).existsSync()){
|
|
||||||
// Debug.LogError("No game installed to uninstall");
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
isUninstalling = true;
|
isUninstalling = true;
|
||||||
setState(() {});
|
setState(() {});
|
||||||
|
|
@ -592,322 +366,4 @@ class _HomePageState extends State<HomePage> {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget Dashboard() {
|
|
||||||
GameData selectedGameData = Backend.Games[dashboardSelectedGameIndex];
|
|
||||||
String filePath = InstallHelper.GetFilePath(dashboardSelectedGameIndex);
|
|
||||||
bool folderExists = Directory(filePath).existsSync();
|
|
||||||
String ActionBtnTxt = "Install";
|
|
||||||
|
|
||||||
if (missingFilesForSelectedGame.length <= 0) {
|
|
||||||
ActionBtnTxt = "Play";
|
|
||||||
} else {
|
|
||||||
ActionBtnTxt =
|
|
||||||
("Download ${FileHashEntry.getTotalSizeInMbytes(missingFilesForSelectedGame).toStringAsFixed(0)} MB");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (calculatingFiles) {
|
|
||||||
ActionBtnTxt = "Validating";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (downloadQueue.containsKey(dashboardSelectedGameIndex)) {
|
|
||||||
ActionBtnTxt = "Downloading";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isUninstalling) {
|
|
||||||
ActionBtnTxt = "Uninstalling";
|
|
||||||
}
|
|
||||||
|
|
||||||
if(runningProcs.containsKey(dashboardSelectedGameIndex)){
|
|
||||||
ActionBtnTxt = "Running";
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget ActionButton = GlassButton(
|
|
||||||
onTap: OnGameActionButtonClicked,
|
|
||||||
child: Text(ActionBtnTxt),
|
|
||||||
width: 200,
|
|
||||||
color: Colors.blue,
|
|
||||||
opacity: 0.5,
|
|
||||||
height: 50);
|
|
||||||
|
|
||||||
final screenHeight = MediaQuery.of(context).size.height;
|
|
||||||
List<DataRow> leaderboardList = [];
|
|
||||||
// leaderboardList.add(TableRow(children: [Text("username"),Text("kills"), Text("deaths")]));
|
|
||||||
// leaderboardList.add(TableRow());
|
|
||||||
leaderboardList
|
|
||||||
.addAll(List.generate(leaderboardForSelectedGame.length, (i) {
|
|
||||||
return DataRow(cells: <DataCell>[
|
|
||||||
DataCell(Text(leaderboardForSelectedGame[i].place.toString())),
|
|
||||||
DataCell(Text(leaderboardForSelectedGame[i].username)),
|
|
||||||
DataCell(Text(leaderboardForSelectedGame[i].kills.toString())),
|
|
||||||
DataCell(Text(leaderboardForSelectedGame[i].deaths.toString())),
|
|
||||||
DataCell(Text(leaderboardForSelectedGame[i].xp.toString())),
|
|
||||||
]);
|
|
||||||
}));
|
|
||||||
|
|
||||||
return Theme(
|
|
||||||
data: ThemeData(splashColor: Colors.transparent),
|
|
||||||
child: Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
height: screenHeight * 0.18,
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
selectedGameData.name,
|
|
||||||
style: TextStyle(fontSize: 25),
|
|
||||||
),
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: List.generate(Backend.Games.length, (index) {
|
|
||||||
bool isSelected = index == dashboardSelectedGameIndex;
|
|
||||||
return InkWell(
|
|
||||||
onTap: () {
|
|
||||||
SetSelectedDashboardGame(index);
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
child: AnimatedContainer(
|
|
||||||
duration: const Duration(milliseconds: 100),
|
|
||||||
margin: EdgeInsets.all(9),
|
|
||||||
height: 80 * (isSelected ? 1.5 : 1),
|
|
||||||
width: 130 * (isSelected ? 1.5 : 1),
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
image: DecorationImage(
|
|
||||||
image:
|
|
||||||
AssetImage(Backend.Games[index].imagePath),
|
|
||||||
fit: BoxFit.fill),
|
|
||||||
borderRadius: BorderRadius.circular(20)),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
!Backend.Games[dashboardSelectedGameIndex].isAvailable
|
|
||||||
? Center(
|
|
||||||
child: Text("Coming Soon", style: TextStyle(fontSize: 40)))
|
|
||||||
: Container(
|
|
||||||
height: screenHeight * 0.72,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 50),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
ActionButton,
|
|
||||||
PopupMenuButton<String>(
|
|
||||||
iconColor: Colors.blueGrey,
|
|
||||||
onSelected: (val) {
|
|
||||||
if (val
|
|
||||||
.toLowerCase()
|
|
||||||
.contains("uninstall")) {
|
|
||||||
UninstallGame(dashboardSelectedGameIndex);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
itemBuilder: (BuildContext context) {
|
|
||||||
return {'Uninstall'}.map((String choice) {
|
|
||||||
return PopupMenuItem<String>(
|
|
||||||
value: choice,
|
|
||||||
child: Text(choice),
|
|
||||||
);
|
|
||||||
}).toList();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
|
|
||||||
],
|
|
||||||
),
|
|
||||||
GlassCard(
|
|
||||||
color: Colors.green,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Text("My Stats",
|
|
||||||
style:
|
|
||||||
TextStyle(color: Colors.blueGrey)),
|
|
||||||
SizedBox(
|
|
||||||
width: 50,
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: Text(
|
|
||||||
"Kills : ${(myStatsForSelectedGame['kills'] ?? "0")}"),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: Text(
|
|
||||||
"Deaths : ${(myStatsForSelectedGame['deaths'] ?? "0")}"),
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: Text(
|
|
||||||
"Assist : ${(myStatsForSelectedGame['assists'] ?? "0")}"),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
height: screenHeight * 0.6,
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
||||||
children: [
|
|
||||||
|
|
||||||
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(20.0),
|
|
||||||
child: GlassCard(
|
|
||||||
child: Container(
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10),
|
|
||||||
width: 350,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
vertical: 12.0, horizontal: 20),
|
|
||||||
child: Text(
|
|
||||||
"News",
|
|
||||||
style: TextStyle(fontSize: 20),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Expanded(
|
|
||||||
child: SingleChildScrollView(
|
|
||||||
child: Column(
|
|
||||||
children: List.generate(
|
|
||||||
newsForSelectedGame.length,
|
|
||||||
(index) {
|
|
||||||
return NewsCard(
|
|
||||||
newsForSelectedGame[index]
|
|
||||||
['title'],
|
|
||||||
newsForSelectedGame[index]
|
|
||||||
['message']);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)),
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
width: 50,
|
|
||||||
),
|
|
||||||
SingleChildScrollView(
|
|
||||||
scrollDirection: Axis.vertical,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(
|
|
||||||
0, 20, 0, 0),
|
|
||||||
child: Text(
|
|
||||||
"Leaderboard",
|
|
||||||
style: TextStyle(fontSize: 20),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
DataTable(
|
|
||||||
dataTextStyle:
|
|
||||||
TextStyle(color: Colors.white),
|
|
||||||
headingTextStyle:
|
|
||||||
TextStyle(color: Colors.white),
|
|
||||||
dividerThickness: 0,
|
|
||||||
columns: [
|
|
||||||
DataColumn(
|
|
||||||
label:
|
|
||||||
Expanded(child: Text("Place"))),
|
|
||||||
DataColumn(
|
|
||||||
label: Expanded(
|
|
||||||
child: Text("Username"))),
|
|
||||||
DataColumn(
|
|
||||||
label:
|
|
||||||
Expanded(child: Text("Kills"))),
|
|
||||||
DataColumn(
|
|
||||||
label: Expanded(
|
|
||||||
child: Text("Deaths"))),
|
|
||||||
DataColumn(
|
|
||||||
label: Expanded(child: Text("XP"))),
|
|
||||||
],
|
|
||||||
rows: leaderboardList,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
))
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
//Install path footer
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10),
|
|
||||||
alignment: Alignment.bottomCenter,
|
|
||||||
child: Column(
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
Row(children: [Text("Install path "), Text(filePath)]),
|
|
||||||
GlassButton(
|
|
||||||
onTap: () {
|
|
||||||
DirectoryPicker file = DirectoryPicker();
|
|
||||||
final dir = file.getDirectory();
|
|
||||||
Backend.prefs!.setString(
|
|
||||||
'${selectedGameData.name}_path', dir!.path);
|
|
||||||
setState(() {});
|
|
||||||
},
|
|
||||||
child: Text("Change Install Location"),
|
|
||||||
width: 250)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 10,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget NewsCard(String title, String message) {
|
|
||||||
return Padding(
|
|
||||||
padding: const EdgeInsets.all(5.0),
|
|
||||||
child: GlassCard(
|
|
||||||
child: Row(
|
|
||||||
children: [
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.all(18.0),
|
|
||||||
child: Icon(
|
|
||||||
Icons.newspaper,
|
|
||||||
color: Colors.blueGrey,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
|
||||||
children: [
|
|
||||||
Text(
|
|
||||||
title,
|
|
||||||
style: TextStyle(fontSize: 18),
|
|
||||||
textAlign: TextAlign.left,
|
|
||||||
),
|
|
||||||
Text(
|
|
||||||
message,
|
|
||||||
overflow: TextOverflow.clip,
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
194
lib/login.dart
194
lib/login.dart
|
|
@ -1,12 +1,17 @@
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mhunt_launcher/Backend/Backend.dart';
|
import 'package:mhunt_launcher/Backend/Backend.dart';
|
||||||
|
import 'package:mhunt_launcher/Backend/DebugHelper.dart';
|
||||||
import 'package:mhunt_launcher/Widgets/CustomWidgets.dart';
|
import 'package:mhunt_launcher/Widgets/CustomWidgets.dart';
|
||||||
import 'package:mhunt_launcher/home.dart';
|
import 'package:mhunt_launcher/home.dart';
|
||||||
import 'package:shared_preferences/shared_preferences.dart';
|
import 'package:shared_preferences/shared_preferences.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
import 'Shared/Dialogs.dart';
|
||||||
|
|
||||||
class LoginPage extends StatefulWidget {
|
class LoginPage extends StatefulWidget {
|
||||||
const LoginPage({super.key});
|
const LoginPage({super.key});
|
||||||
|
|
||||||
|
|
@ -32,7 +37,6 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
if (prefs.containsKey("username") && prefs.containsKey("password")) {
|
if (prefs.containsKey("username") && prefs.containsKey("password")) {
|
||||||
usernameController.text = prefs.getString("username") ?? '';
|
usernameController.text = prefs.getString("username") ?? '';
|
||||||
passwordController.text = prefs.getString("password") ?? '';
|
passwordController.text = prefs.getString("password") ?? '';
|
||||||
|
|
||||||
LoginOrReg();
|
LoginOrReg();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -48,6 +52,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
}
|
}
|
||||||
|
|
||||||
TextEditingController usernameController = TextEditingController();
|
TextEditingController usernameController = TextEditingController();
|
||||||
|
TextEditingController gamertagController = TextEditingController();
|
||||||
TextEditingController passwordController = TextEditingController();
|
TextEditingController passwordController = TextEditingController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|
@ -64,7 +69,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
},
|
},
|
||||||
child: Center(
|
child: Center(
|
||||||
child: web3LoginCard()
|
child: TraditionalLoginCard()
|
||||||
))
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -145,7 +150,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
setState(() {
|
setState(() {
|
||||||
web3loginState = 1;
|
web3loginState = 1;
|
||||||
});
|
});
|
||||||
launchUrl(Uri.parse('https://auth.playpoolstudios.com/?request_id=${requestId}'));
|
launchUrl(Uri.parse('https://auth.playpoolstudios.com/auth/?request_id=${requestId}'));
|
||||||
String requestResponse = "-1";
|
String requestResponse = "-1";
|
||||||
while(requestResponse == "-1"){
|
while(requestResponse == "-1"){
|
||||||
await Future.delayed(const Duration(seconds: 1));
|
await Future.delayed(const Duration(seconds: 1));
|
||||||
|
|
@ -190,72 +195,120 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
}
|
}
|
||||||
|
|
||||||
await Backend.Register(web3id,web3id,usernameEditingController.text);
|
await Backend.Register(web3id,web3id,usernameEditingController.text);
|
||||||
await Backend.Login(usernameEditingController.text, web3id);
|
await Backend.Login(web3id, web3id);
|
||||||
|
|
||||||
OnLoginSuccess();
|
OnLoginSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isGuest = false;
|
||||||
Widget TraditionalLoginCard(){
|
Widget TraditionalLoginCard(){
|
||||||
return GlassCard(
|
return GlassCard(
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.all(25),
|
padding: EdgeInsets.all(25),
|
||||||
width: 600,
|
width: 600,
|
||||||
height: 400,
|
height: 400,
|
||||||
child: Column(
|
child: isGuest? TraditionalLoginGuest() :TraditionalLoginMain()
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
||||||
children: [
|
|
||||||
const Text(
|
|
||||||
"Welcome to W3B Launcher",
|
|
||||||
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
|
|
||||||
),
|
|
||||||
Column(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
Text("Username "),
|
|
||||||
SizedBox(
|
|
||||||
width: 300,
|
|
||||||
child: TextField(
|
|
||||||
controller: usernameController,
|
|
||||||
))
|
|
||||||
],
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
),
|
|
||||||
Row(children: [
|
|
||||||
Text("Password "),
|
|
||||||
SizedBox(
|
|
||||||
width: 300,
|
|
||||||
child: TextField(
|
|
||||||
controller: passwordController,
|
|
||||||
))
|
|
||||||
], mainAxisAlignment: MainAxisAlignment.center),
|
|
||||||
SizedBox(
|
|
||||||
height: 30,
|
|
||||||
),
|
|
||||||
GlassButton(onTap: LoginOrReg, child: Text(isReg ? "Register" : "Login"), width: 150, height: 40),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
Row(children: [
|
|
||||||
Text(isReg ? "Already have an Account? " : "Don't have an Account? "),
|
|
||||||
InkWell(
|
|
||||||
child: Text(
|
|
||||||
isReg ? "Login Here" : "Register Here",
|
|
||||||
style: TextStyle(color: Colors.blue),
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
setState(() {
|
|
||||||
isReg = !isReg;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
)
|
|
||||||
], mainAxisAlignment: MainAxisAlignment.center)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget TraditionalLoginMain(){
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
"Welcome to W3B Launcher",
|
||||||
|
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text("Username "),
|
||||||
|
SizedBox(
|
||||||
|
width: 300,
|
||||||
|
child: TextField(
|
||||||
|
controller: usernameController,
|
||||||
|
))
|
||||||
|
],
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
),
|
||||||
|
Row(children: [
|
||||||
|
Text("Password "),
|
||||||
|
SizedBox(
|
||||||
|
width: 300,
|
||||||
|
child: TextField(
|
||||||
|
controller: passwordController,
|
||||||
|
))
|
||||||
|
], mainAxisAlignment: MainAxisAlignment.center),
|
||||||
|
SizedBox(
|
||||||
|
height: 30,
|
||||||
|
),
|
||||||
|
GlassButton(onTap: LoginOrReg, child: Text(isReg ? "Register" : "Login"), width: 150, height: 40),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
Row(children: [
|
||||||
|
Text(isReg ? "Already have an Account? " : "Don't have an Account? "),
|
||||||
|
InkWell(
|
||||||
|
child: Text(
|
||||||
|
isReg ? "Login Here" : "Register Here",
|
||||||
|
style: TextStyle(color: Colors.blue),
|
||||||
|
),
|
||||||
|
onTap: () {
|
||||||
|
setState(() {
|
||||||
|
isReg = !isReg;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
)
|
||||||
|
], mainAxisAlignment: MainAxisAlignment.center),
|
||||||
|
GlassButton(onTap: (){setState(() {
|
||||||
|
isGuest=true;
|
||||||
|
});}, child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Icon(Icons.person),
|
||||||
|
SizedBox(width: 10,),
|
||||||
|
Text("Guest Mode"),
|
||||||
|
],
|
||||||
|
), width: 130, height: 30)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget TraditionalLoginGuest(){
|
||||||
|
return Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
const Text(
|
||||||
|
"Welcome to W3B Launcher - Guest Mode",
|
||||||
|
style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold),
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
Text("Gamer Tag "),
|
||||||
|
SizedBox(
|
||||||
|
width: 300,
|
||||||
|
child: TextField(
|
||||||
|
controller: gamertagController,
|
||||||
|
))
|
||||||
|
],
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
),
|
||||||
|
SizedBox(height: 15,),
|
||||||
|
SizedBox(width: 250,child:usernameExists ? Text("Username is taken",style: TextStyle(color: Colors.red),) : Container()),
|
||||||
|
|
||||||
|
GlassButton(onTap:GuestModeComplete , child: Text("Complete Login"), width: 250,height: 40,color: Colors.green)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
GlassButton(onTap: (){setState(() {
|
||||||
|
isGuest=false;
|
||||||
|
});}, child: Text("Back"), width: 200, color: Colors.blueGrey)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
void LoginOrReg() async {
|
void LoginOrReg() async {
|
||||||
// if(kDebugMode){
|
// if(kDebugMode){
|
||||||
// Navigator.of(context).push(MaterialPageRoute(builder: (context)=>HomePage()));
|
// Navigator.of(context).push(MaterialPageRoute(builder: (context)=>HomePage()));
|
||||||
|
|
@ -268,8 +321,35 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
success = await Backend.Login(usernameController.text, passwordController.text);
|
success = await Backend.Login(usernameController.text, passwordController.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Debug.Log('${isReg ? "Register": "Login"} was ${success ? "success" : "faild"}');
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
OnLoginSuccess();
|
OnLoginSuccess();
|
||||||
|
}else{
|
||||||
|
if(isReg){
|
||||||
|
Dialogs.showAlertDialog(context, 'Failed Register', "Username already exists");
|
||||||
|
}else{
|
||||||
|
Dialogs.showAlertDialog(context, 'Failed Login', "Username or Password is incorrect");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GuestModeComplete()async{
|
||||||
|
|
||||||
|
bool usernameValidated = await Backend.GetUsernameValidation(gamertagController.text);
|
||||||
|
if(!usernameValidated){
|
||||||
|
setState(() {
|
||||||
|
usernameExists=true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
String username = await Backend.GetNextGuestUsername();
|
||||||
|
bool success= await Backend.Register(username, username, gamertagController.text);
|
||||||
|
|
||||||
|
if(success){
|
||||||
|
usernameController.text = username;
|
||||||
|
passwordController.text = username;
|
||||||
|
OnLoginSuccess();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -277,7 +357,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
prefs.setString('username', usernameController.text);
|
prefs.setString('username', usernameController.text);
|
||||||
prefs.setString('password', passwordController.text);
|
prefs.setString('password', passwordController.text);
|
||||||
|
prefs.setString('displayname', Backend.displayName);
|
||||||
Navigator.of(context).push(MaterialPageRoute(builder: (context) => HomePage()));
|
Navigator.of(context).push(MaterialPageRoute(builder: (context) => HomePage()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
BIN
ota/Microsoft.CSharp.dll
Normal file
BIN
ota/Microsoft.CSharp.dll
Normal file
Binary file not shown.
BIN
ota/Microsoft.DiaSymReader.Native.amd64.dll
Normal file
BIN
ota/Microsoft.DiaSymReader.Native.amd64.dll
Normal file
Binary file not shown.
BIN
ota/Microsoft.VisualBasic.Core.dll
Normal file
BIN
ota/Microsoft.VisualBasic.Core.dll
Normal file
Binary file not shown.
BIN
ota/Microsoft.VisualBasic.dll
Normal file
BIN
ota/Microsoft.VisualBasic.dll
Normal file
Binary file not shown.
BIN
ota/Microsoft.Win32.Primitives.dll
Normal file
BIN
ota/Microsoft.Win32.Primitives.dll
Normal file
Binary file not shown.
BIN
ota/Microsoft.Win32.Registry.dll
Normal file
BIN
ota/Microsoft.Win32.Registry.dll
Normal file
Binary file not shown.
BIN
ota/Newtonsoft.Json.dll
Normal file
BIN
ota/Newtonsoft.Json.dll
Normal file
Binary file not shown.
BIN
ota/System.AppContext.dll
Normal file
BIN
ota/System.AppContext.dll
Normal file
Binary file not shown.
BIN
ota/System.Buffers.dll
Normal file
BIN
ota/System.Buffers.dll
Normal file
Binary file not shown.
BIN
ota/System.Collections.Concurrent.dll
Normal file
BIN
ota/System.Collections.Concurrent.dll
Normal file
Binary file not shown.
BIN
ota/System.Collections.Immutable.dll
Normal file
BIN
ota/System.Collections.Immutable.dll
Normal file
Binary file not shown.
BIN
ota/System.Collections.NonGeneric.dll
Normal file
BIN
ota/System.Collections.NonGeneric.dll
Normal file
Binary file not shown.
BIN
ota/System.Collections.Specialized.dll
Normal file
BIN
ota/System.Collections.Specialized.dll
Normal file
Binary file not shown.
BIN
ota/System.Collections.dll
Normal file
BIN
ota/System.Collections.dll
Normal file
Binary file not shown.
BIN
ota/System.ComponentModel.Annotations.dll
Normal file
BIN
ota/System.ComponentModel.Annotations.dll
Normal file
Binary file not shown.
BIN
ota/System.ComponentModel.DataAnnotations.dll
Normal file
BIN
ota/System.ComponentModel.DataAnnotations.dll
Normal file
Binary file not shown.
BIN
ota/System.ComponentModel.EventBasedAsync.dll
Normal file
BIN
ota/System.ComponentModel.EventBasedAsync.dll
Normal file
Binary file not shown.
BIN
ota/System.ComponentModel.Primitives.dll
Normal file
BIN
ota/System.ComponentModel.Primitives.dll
Normal file
Binary file not shown.
BIN
ota/System.ComponentModel.TypeConverter.dll
Normal file
BIN
ota/System.ComponentModel.TypeConverter.dll
Normal file
Binary file not shown.
BIN
ota/System.ComponentModel.dll
Normal file
BIN
ota/System.ComponentModel.dll
Normal file
Binary file not shown.
BIN
ota/System.Configuration.dll
Normal file
BIN
ota/System.Configuration.dll
Normal file
Binary file not shown.
BIN
ota/System.Console.dll
Normal file
BIN
ota/System.Console.dll
Normal file
Binary file not shown.
BIN
ota/System.Core.dll
Normal file
BIN
ota/System.Core.dll
Normal file
Binary file not shown.
BIN
ota/System.Data.Common.dll
Normal file
BIN
ota/System.Data.Common.dll
Normal file
Binary file not shown.
BIN
ota/System.Data.DataSetExtensions.dll
Normal file
BIN
ota/System.Data.DataSetExtensions.dll
Normal file
Binary file not shown.
BIN
ota/System.Data.dll
Normal file
BIN
ota/System.Data.dll
Normal file
Binary file not shown.
BIN
ota/System.Diagnostics.Contracts.dll
Normal file
BIN
ota/System.Diagnostics.Contracts.dll
Normal file
Binary file not shown.
BIN
ota/System.Diagnostics.Debug.dll
Normal file
BIN
ota/System.Diagnostics.Debug.dll
Normal file
Binary file not shown.
BIN
ota/System.Diagnostics.DiagnosticSource.dll
Normal file
BIN
ota/System.Diagnostics.DiagnosticSource.dll
Normal file
Binary file not shown.
BIN
ota/System.Diagnostics.FileVersionInfo.dll
Normal file
BIN
ota/System.Diagnostics.FileVersionInfo.dll
Normal file
Binary file not shown.
BIN
ota/System.Diagnostics.Process.dll
Normal file
BIN
ota/System.Diagnostics.Process.dll
Normal file
Binary file not shown.
BIN
ota/System.Diagnostics.StackTrace.dll
Normal file
BIN
ota/System.Diagnostics.StackTrace.dll
Normal file
Binary file not shown.
BIN
ota/System.Diagnostics.TextWriterTraceListener.dll
Normal file
BIN
ota/System.Diagnostics.TextWriterTraceListener.dll
Normal file
Binary file not shown.
BIN
ota/System.Diagnostics.Tools.dll
Normal file
BIN
ota/System.Diagnostics.Tools.dll
Normal file
Binary file not shown.
BIN
ota/System.Diagnostics.TraceSource.dll
Normal file
BIN
ota/System.Diagnostics.TraceSource.dll
Normal file
Binary file not shown.
BIN
ota/System.Diagnostics.Tracing.dll
Normal file
BIN
ota/System.Diagnostics.Tracing.dll
Normal file
Binary file not shown.
BIN
ota/System.Drawing.Primitives.dll
Normal file
BIN
ota/System.Drawing.Primitives.dll
Normal file
Binary file not shown.
BIN
ota/System.Drawing.dll
Normal file
BIN
ota/System.Drawing.dll
Normal file
Binary file not shown.
BIN
ota/System.Dynamic.Runtime.dll
Normal file
BIN
ota/System.Dynamic.Runtime.dll
Normal file
Binary file not shown.
BIN
ota/System.Formats.Asn1.dll
Normal file
BIN
ota/System.Formats.Asn1.dll
Normal file
Binary file not shown.
BIN
ota/System.Formats.Tar.dll
Normal file
BIN
ota/System.Formats.Tar.dll
Normal file
Binary file not shown.
BIN
ota/System.Globalization.Calendars.dll
Normal file
BIN
ota/System.Globalization.Calendars.dll
Normal file
Binary file not shown.
BIN
ota/System.Globalization.Extensions.dll
Normal file
BIN
ota/System.Globalization.Extensions.dll
Normal file
Binary file not shown.
BIN
ota/System.Globalization.dll
Normal file
BIN
ota/System.Globalization.dll
Normal file
Binary file not shown.
BIN
ota/System.IO.Compression.Brotli.dll
Normal file
BIN
ota/System.IO.Compression.Brotli.dll
Normal file
Binary file not shown.
BIN
ota/System.IO.Compression.FileSystem.dll
Normal file
BIN
ota/System.IO.Compression.FileSystem.dll
Normal file
Binary file not shown.
BIN
ota/System.IO.Compression.Native.dll
Normal file
BIN
ota/System.IO.Compression.Native.dll
Normal file
Binary file not shown.
BIN
ota/System.IO.Compression.ZipFile.dll
Normal file
BIN
ota/System.IO.Compression.ZipFile.dll
Normal file
Binary file not shown.
BIN
ota/System.IO.Compression.dll
Normal file
BIN
ota/System.IO.Compression.dll
Normal file
Binary file not shown.
BIN
ota/System.IO.FileSystem.AccessControl.dll
Normal file
BIN
ota/System.IO.FileSystem.AccessControl.dll
Normal file
Binary file not shown.
BIN
ota/System.IO.FileSystem.DriveInfo.dll
Normal file
BIN
ota/System.IO.FileSystem.DriveInfo.dll
Normal file
Binary file not shown.
BIN
ota/System.IO.FileSystem.Primitives.dll
Normal file
BIN
ota/System.IO.FileSystem.Primitives.dll
Normal file
Binary file not shown.
BIN
ota/System.IO.FileSystem.Watcher.dll
Normal file
BIN
ota/System.IO.FileSystem.Watcher.dll
Normal file
Binary file not shown.
BIN
ota/System.IO.FileSystem.dll
Normal file
BIN
ota/System.IO.FileSystem.dll
Normal file
Binary file not shown.
BIN
ota/System.IO.IsolatedStorage.dll
Normal file
BIN
ota/System.IO.IsolatedStorage.dll
Normal file
Binary file not shown.
BIN
ota/System.IO.MemoryMappedFiles.dll
Normal file
BIN
ota/System.IO.MemoryMappedFiles.dll
Normal file
Binary file not shown.
BIN
ota/System.IO.Pipes.AccessControl.dll
Normal file
BIN
ota/System.IO.Pipes.AccessControl.dll
Normal file
Binary file not shown.
BIN
ota/System.IO.Pipes.dll
Normal file
BIN
ota/System.IO.Pipes.dll
Normal file
Binary file not shown.
BIN
ota/System.IO.UnmanagedMemoryStream.dll
Normal file
BIN
ota/System.IO.UnmanagedMemoryStream.dll
Normal file
Binary file not shown.
BIN
ota/System.IO.dll
Normal file
BIN
ota/System.IO.dll
Normal file
Binary file not shown.
BIN
ota/System.Linq.Expressions.dll
Normal file
BIN
ota/System.Linq.Expressions.dll
Normal file
Binary file not shown.
BIN
ota/System.Linq.Parallel.dll
Normal file
BIN
ota/System.Linq.Parallel.dll
Normal file
Binary file not shown.
BIN
ota/System.Linq.Queryable.dll
Normal file
BIN
ota/System.Linq.Queryable.dll
Normal file
Binary file not shown.
BIN
ota/System.Linq.dll
Normal file
BIN
ota/System.Linq.dll
Normal file
Binary file not shown.
BIN
ota/System.Memory.dll
Normal file
BIN
ota/System.Memory.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.Http.Json.dll
Normal file
BIN
ota/System.Net.Http.Json.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.Http.dll
Normal file
BIN
ota/System.Net.Http.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.HttpListener.dll
Normal file
BIN
ota/System.Net.HttpListener.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.Mail.dll
Normal file
BIN
ota/System.Net.Mail.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.NameResolution.dll
Normal file
BIN
ota/System.Net.NameResolution.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.NetworkInformation.dll
Normal file
BIN
ota/System.Net.NetworkInformation.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.Ping.dll
Normal file
BIN
ota/System.Net.Ping.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.Primitives.dll
Normal file
BIN
ota/System.Net.Primitives.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.Quic.dll
Normal file
BIN
ota/System.Net.Quic.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.Requests.dll
Normal file
BIN
ota/System.Net.Requests.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.Security.dll
Normal file
BIN
ota/System.Net.Security.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.ServicePoint.dll
Normal file
BIN
ota/System.Net.ServicePoint.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.Sockets.dll
Normal file
BIN
ota/System.Net.Sockets.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.WebClient.dll
Normal file
BIN
ota/System.Net.WebClient.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.WebHeaderCollection.dll
Normal file
BIN
ota/System.Net.WebHeaderCollection.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.WebProxy.dll
Normal file
BIN
ota/System.Net.WebProxy.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.WebSockets.Client.dll
Normal file
BIN
ota/System.Net.WebSockets.Client.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.WebSockets.dll
Normal file
BIN
ota/System.Net.WebSockets.dll
Normal file
Binary file not shown.
BIN
ota/System.Net.dll
Normal file
BIN
ota/System.Net.dll
Normal file
Binary file not shown.
BIN
ota/System.Numerics.Vectors.dll
Normal file
BIN
ota/System.Numerics.Vectors.dll
Normal file
Binary file not shown.
BIN
ota/System.Numerics.dll
Normal file
BIN
ota/System.Numerics.dll
Normal file
Binary file not shown.
BIN
ota/System.ObjectModel.dll
Normal file
BIN
ota/System.ObjectModel.dll
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user