This commit is contained in:
Sewmina 2025-01-25 12:01:14 +05:30
parent 626f2eb2e4
commit 33be6d0221
18 changed files with 710 additions and 220 deletions

View File

@ -1,5 +1,8 @@
plugins {
id "com.android.application"
// START: FlutterFire Configuration
id 'com.google.gms.google-services'
// END: FlutterFire Configuration
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}

View File

@ -0,0 +1,39 @@
{
"project_info": {
"project_number": "652710461284",
"project_id": "sologin-55bbd",
"storage_bucket": "sologin-55bbd.firebasestorage.app"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:652710461284:android:44b78de76f4d6f88f54471",
"android_client_info": {
"package_name": "com.xperience_mhunt_launcher.mhunt_launcher"
}
},
"oauth_client": [
{
"client_id": "652710461284-7e2909o0bmsqqo17l4fhtkm33emh35vj.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyDyWHadwDE-CAtMbKfZ7Llq18zGMDPyRpY"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "652710461284-7e2909o0bmsqqo17l4fhtkm33emh35vj.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}

View File

@ -20,6 +20,9 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.0" apply false
// START: FlutterFire Configuration
id "com.google.gms.google-services" version "4.3.15" apply false
// END: FlutterFire Configuration
id "org.jetbrains.kotlin.android" version "1.7.10" apply false
}

1
firebase.json Normal file
View File

@ -0,0 +1 @@
{"flutter":{"platforms":{"android":{"default":{"projectId":"sologin-55bbd","appId":"1:652710461284:android:44b78de76f4d6f88f54471","fileOutput":"android/app/google-services.json"}},"dart":{"lib/firebase_options.dart":{"projectId":"sologin-55bbd","configurations":{"android":"1:652710461284:android:44b78de76f4d6f88f54471","ios":"1:652710461284:ios:6eee89e45d69a3d1f54471","macos":"1:652710461284:ios:bae7c085a1ba8dfbf54471","windows":"1:652710461284:web:4d52a8a41d1f3ae2f54471"}}}}}}

View File

@ -11,6 +11,7 @@ import 'DebugHelper.dart';
class Backend {
static const String API_ENDPOINT = Helpers.WEB2_ENDPOINT;
static const String GUEST_PREFIX = "slguest";
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"),
@ -23,6 +24,7 @@ class Backend {
static String displayName = "";
static String walletAddress = "";
static String pubKey = "";
static String ticketsATA = "";
static int SolBalance =0;
static int TicketsBalance = 0;
@ -32,16 +34,16 @@ class Backend {
var loginResponse = null;
init();
try {
loginResponse = (await http.post(Uri.parse('${API_ENDPOINT}login.php'), body: <String, String>{"username": username, "password": password}));
Debug.LogResponse(loginResponse.body.toString(), src: '${API_ENDPOINT}login.php');
String url = '${API_ENDPOINT}login.php';
loginResponse = (await http.post(Uri.parse(url), body: <String, String>{"username": username, "password": password}));
Debug.LogResponse(loginResponse.body.toString(), src: url);
if(loginResponse.body.toString().contains("no user")){
return false;
}
try {
Username = username;
displayName = username;
dynamic responseJson = jsonDecode(loginResponse.body.toString());
displayName = responseJson['display_name'];
SetUsernamePassword(username, password);
return true;
@ -86,6 +88,8 @@ class Backend {
var response = await http.get(Uri.parse(url));
Debug.LogResponse(response.body.toString(), src: url);
pubKey = jsonDecode(response.body.toString())["pub_key"];
ticketsATA = await GetTicketsAccount();
return pubKey;
}
@ -95,17 +99,51 @@ class Backend {
}
static Future<int> GetSolBalance() async{
String url ='${API_ENDPOINT}get_wallet_balance.php?wallet=${pubKey}';
var response = await http.get(Uri.parse(url));
Debug.LogResponse(response.body.toString(), src: url);
return jsonDecode(response.body.toString())["balance"];
try {
String url = '${API_ENDPOINT}get_wallet_balance.php?wallet=${pubKey}';
var response = await http.get(Uri.parse(url));
Debug.LogResponse(response.body.toString(), src: url);
return jsonDecode(response.body.toString())["balance"];
}catch(e){
return 0;
}
}
static Future<int> GetTicketsBalance() async{
String url ='${API_ENDPOINT}get_tickets_balance.php?wallet=${pubKey}';
try {
String url = '${API_ENDPOINT}get_tickets_balance.php?wallet=${pubKey}';
var response = await http.get(Uri.parse(url));
Debug.LogResponse(response.body.toString(), src: url);
String balanceString = jsonDecode(response.body.toString())["balance"];
return int.parse(balanceString);
}catch(e){
return 0;
}
}
static Future<String> GetTicketsAccount() async{
try {
String url = '${Helpers.SOBRIDGE_ENDPOINT}getTicketsATA?wallet=${pubKey}';
var response = await http.get(Uri.parse(url));
Debug.LogResponse(response.body.toString(), src: url);
return jsonDecode(response.body.toString())["ATA"];
}catch(e){
return "";
}
}
static Future<dynamic> PurchaseTickets(int amount) async{
String email = UserJson['username'];
String password = UserJson['passwd'];
String url ='${Helpers.SOBRIDGE_ENDPOINT}purchaseTickets?email=$email&password=$password&amount=$amount';
Debug.Log("Requesting ticket purchase");
var response = await http.get(Uri.parse(url));
Debug.LogResponse(response.body.toString(), src: url);
return jsonDecode(response.body.toString())["balance"];
dynamic resJson = jsonDecode(response.body.toString());
return resJson;
}
static void SetUsernamePassword(String username, String passwd) {
@ -192,7 +230,7 @@ class Backend {
try {
String url = '${API_ENDPOINT}get_display_name.php';
response = (await http.post(Uri.parse(url), body: <String, String>{"id": id.toString()}));
Debug.LogResponse(response.body.toString(), src: url);
Debug.LogResponse(response.body.toString()+":id=${id}", src: url);
return response.body;
} catch (e) {
@ -235,6 +273,19 @@ class Backend {
return 'guest ${random.nextInt(10000000)}';
}
static Future<String> CreateNewRequest() async{
try{
String url = '${API_ENDPOINT}create_new_request.php';
var response = await http.get(Uri.parse(url));
Debug.LogResponse(response.body.toString(), src:url);
return response.body.toString();
}catch(e){
}
return "";
}
static VaultData vault = VaultData('0x0', 0, 0);
static Future<VaultData> RefreshVaultData() async{

View File

@ -51,7 +51,7 @@ class InstallHelper{
//Get remote hashtable
String link ='${Backend.API_ENDPOINT}${Backend.Games[gameId].code}/get_hashes.php';
var remoteHashResponse = (await http.post(Uri.parse(link)));
Debug.LogResponse(remoteHashResponse.body.toString(),src: link);
// Debug.LogResponse(remoteHashResponse.body.toString(),src: link);
List<FileHashEntry> remoteList = FileHashEntry.listFromJson(remoteHashResponse.body.toString());
//Comapreeee

View File

@ -1,7 +1,11 @@
class Helpers{
static const int LAMPORTS_PER_SOL = 1000000000;
static const int TICKET_PRICE = 300000000;
static const String DASHBOARD_URL = 'https://auth.playpoolstudios.com';
static const String WEB2_ENDPOINT = "https://vps.playpoolstudios.com/metahunt/api/launcher/";
static const String SOBRIDGE_ENDPOINT = "http://vps.playpoolstudios.com:20117/";
static const String MOONPAY_URL = 'http://vps.playpoolstudios.com:3640';
static String trimTrailingZeros(double number) {

View File

@ -2,10 +2,13 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:mhunt_launcher/Shared/Helpers.dart';
import 'package:mhunt_launcher/Shared/TextStyles.dart';
import 'package:mhunt_launcher/login.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:toastification/toastification.dart';
import 'package:url_launcher/url_launcher_string.dart';
import '../../../Backend/Backend.dart';
import '../../../Shared/Dialogs.dart';
import '../../CustomWidgets.dart';
import 'BuyDialog.dart';
@ -13,155 +16,201 @@ Widget AccountPage(BuildContext context, Function onUpdate) {
return Padding(
padding: const EdgeInsets.all(25.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
Column(
children: [
Text("Hello, ${Backend.displayName}",
style: TextStyle(fontSize: 30)),
],
),
SizedBox(
height: 100,
),
GlassCard(
child: Container(
padding: const EdgeInsets.all(12.0),
margin: const EdgeInsets.symmetric(horizontal: 50),
child: Row(
mainAxisSize: MainAxisSize.min,
Row(
children: [
Column(
children: [
Text("Solana Wallet Address", style: TextStyles.title2BTextStyle,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(Backend.pubKey),
InkWell(
onTap: ()async {
await Clipboard.setData(ClipboardData(text: Backend.pubKey));
toastification.show(
context: context, // optional if you use ToastificationWrapper
title: Text('Wallet address copied to clipboard'),
autoCloseDuration: const Duration(seconds: 2),
style: ToastificationStyle.simple,
);
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Icon(Icons.copy),
),
)
],
),
],
),
SizedBox(width: 50,),
Row(
children: [
Column(
children: [
Text("SOL Balance", style: TextStyles.title2BTextStyle,),
Text('${Helpers.trimTrailingZeros(Backend.SolBalance / Helpers.LAMPORTS_PER_SOL).toString()} SOL')
],
),
InkWell(
onTap: ()async{
await Backend.GetWalletBalance();
onUpdate();
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(Icons.refresh),
),
)
],
)
],
),
),
),
SizedBox(
height: 20,
),
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),
),
],
)
Text("Hello, ${Backend.displayName}",
style: TextStyle(fontSize: 30)),
],
),
SizedBox(
width: 60,
height: 100,
),
Column(
children: [
Text(
"Tickets",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
Row(
GlassCard(
child: Container(
padding: const EdgeInsets.all(12.0),
margin: const EdgeInsets.symmetric(horizontal: 50),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.airplane_ticket_rounded,
color: Colors.amber,
size: 35,
),
Text(
Backend.TicketsBalance.toString(),
style: TextStyle(fontSize: 50),
InkWell(
onTap: (){
launchUrlString('https://explorer.solana.com/address/${Backend.pubKey}?cluster=devnet');
},
child: Column(
children: [
Text("Solana Wallet Address", style: TextStyles.title2BTextStyle,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(Backend.pubKey),
InkWell(
onTap: ()async {
await Clipboard.setData(ClipboardData(text: Backend.pubKey));
toastification.show(
context: context, // optional if you use ToastificationWrapper
title: Text('Wallet address copied to clipboard'),
autoCloseDuration: const Duration(seconds: 2),
style: ToastificationStyle.simple,
);
},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10),
child: Icon(Icons.copy),
),
)
],
),
],
),
),
SizedBox(width: 50,),
Row(
children: [
Column(
children: [
Text("SOL Balance", style: TextStyles.title2BTextStyle,),
Text('${Helpers.trimTrailingZeros(Backend.SolBalance / Helpers.LAMPORTS_PER_SOL).toString()} SOL')
],
),
InkWell(
onTap: ()async{
await Backend.GetWalletBalance();
onUpdate();
},
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Icon(Icons.refresh),
),
)
],
)
],
),
GlassButton(
onTap: () {
Navigator.of(context).restorablePush(buyTicketsDialogBuilder);
}, child: Text("Buy Tickets"), width: 100)
],
),
),
],
),
SizedBox(
height: 50,
),
GlassButton(
onTap: () {
launchUrlString(Helpers.DASHBOARD_URL);
},
child: Row(
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Open Dashboard"),
SizedBox(
width: 10,
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(
"Tickets",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 15),
),
InkWell(
onTap: (){
launchUrlString('https://explorer.solana.com/address/${Backend.ticketsATA}?cluster=devnet');
},
child: Row(
children: [
Icon(
Icons.airplane_ticket_rounded,
color: Colors.amber,
size: 35,
),
Text(
Backend.TicketsBalance.toString(),
style: TextStyle(fontSize: 50),
),
],
),
),
GlassButton(
onTap: (){OnPurchaseClicked(context);}, child: Text("Buy Tickets"), width: 100)
],
),
Icon(Icons.open_in_new, color: Colors.grey)
],
),
width: 250,
height: 50)
SizedBox(
height: 50,
),
GlassButton(
onTap: () {
launchUrlString(Helpers.DASHBOARD_URL);
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Open Dashboard"),
SizedBox(
width: 10,
),
Icon(Icons.open_in_new, color: Colors.grey)
],
),
width: 250,
height: 50),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(),
GlassButton(
color: Colors.red,
onTap: ()async {
var prefs = await SharedPreferences.getInstance();
prefs.clear();
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => LoginPage()));
},
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text("Logout"),
SizedBox(
width: 10,
),
Icon(Icons.logout, color: Colors.grey)
],
),
width: 150,
height: 50),
],
)
],
),
);
}
void OnPurchaseClicked(BuildContext context){
Navigator.of(context).restorablePush(buyTicketsDialogBuilder);
}

View File

@ -1,85 +1,183 @@
import 'package:flutter/material.dart';
import 'package:mhunt_launcher/Widgets/CustomWidgets.dart';
import 'package:toastification/toastification.dart';
import 'package:url_launcher/url_launcher_string.dart';
Route<Object?> buyTicketsDialogBuilder(BuildContext context, Object? arguments) {
import '../../../Backend/Backend.dart';
import '../../../Backend/DebugHelper.dart';
import '../../../Shared/Dialogs.dart';
import '../../../Shared/Helpers.dart';
import '../../../Shared/TextStyles.dart';
Route<Object?> buyTicketsDialogBuilder(
BuildContext context, Object? arguments) {
return DialogRoute<void>(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('How many Tickets?'),
content: PurchaseTicketsContent(),
actions: <Widget>[
TextButton(
style: TextButton.styleFrom(
textStyle: Theme.of(context).textTheme.labelLarge,
),
child: const Text('Purchase',style: TextStyle(color: Colors.green),),
onPressed: () {
// Handle the purchase with the selected ticketCount
Navigator.of(context).pop();
},
),
TextButton(
style: TextButton.styleFrom(
textStyle: Theme.of(context).textTheme.labelLarge,
),
child: const Text('Cancel'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
class PurchaseTicketsContent extends StatefulWidget {
const PurchaseTicketsContent({super.key});
@override
State<PurchaseTicketsContent> createState() => _PurchaseTicketsContentState();
}
int ticketCount = 1;
bool isLoading = false;
class _PurchaseTicketsContentState extends State<PurchaseTicketsContent> {
@override
void initState() {
// TODO: implement initState
super.initState();
isLoading=false;
setState(() {
});
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
return isLoading ? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Select an amount of Tickets you want to purchase',
),
SizedBox(height: 20,),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: () {
setState(() {
if (ticketCount > 1) ticketCount--;
});
},
child: Icon(Icons.remove_circle),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'$ticketCount',
style: TextStyle(fontSize: 40),
),
),
InkWell(
onTap: () {
setState(() {
ticketCount++;
});
},
child: Icon(Icons.add_circle_rounded),
),
],
)
Text("Loading... Please wait"),
],
) :BuyWindow(
context: context,
onTicketDecrease: () => {
setState(() {
if (ticketCount > 1) ticketCount--;
})
},
onTicketIncrease: () => {
setState(() {
ticketCount++;
})
},
onPurchase: ()async{
setState(() {
isLoading=true;
});
dynamic result =await Backend.PurchaseTickets(ticketCount);
if(result['status'] == "Success"){
toastification.show(
context: context, // optional if you use ToastificationWrapper
title: Text('$ticketCount Tickets purchased successfully, Click to show Transaction'),
callbacks: ToastificationCallbacks(
onTap: (toastItem){
launchUrlString('https://explorer.solana.com/tx/${result['tx']}?cluster=devnet');
}
),
autoCloseDuration: const Duration(seconds: 10),
style: ToastificationStyle.simple,
);
}
Navigator.of(context).pop();
}
);
}
}
}
Widget BuyWindow(
{required BuildContext context,
required Function() onTicketDecrease,
required Function() onTicketIncrease,
required Function() onPurchase
}) {
int totalCostLamports = Helpers.TICKET_PRICE * ticketCount;
double totalCostSol = totalCostLamports / Helpers.LAMPORTS_PER_SOL;
bool hasEnoughSol = Backend.SolBalance > totalCostLamports;
Debug.Log(
'I have ${Backend.SolBalance} LAMPORTS, Ticket price is ${totalCostLamports}, do I have enough? :${hasEnoughSol}');
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
'Select an amount of Tickets you want to purchase',
),
SizedBox(
height: 20,
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
InkWell(
onTap: onTicketDecrease,
child: Icon(Icons.remove_circle),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'$ticketCount',
style: TextStyle(fontSize: 40),
),
),
InkWell(
onTap: onTicketIncrease,
child: Icon(Icons.add_circle_rounded),
),
],
),
Column(
children: [
Text(
'${Helpers.trimTrailingZeros(totalCostSol)} SOL',
style: TextStyles.titleTextStyle,
),
(!hasEnoughSol
? Text(
"Insufficient balance",
style: TextStyle(color: Colors.red),
)
: Container())
],
),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
(hasEnoughSol
? GlassButton(
onTap: onPurchase,
child: Text("Purchase"),
width: 250,
color: Colors.green)
: GlassButton(
onTap: () {
launchUrlString(
'${Helpers.MOONPAY_URL}/?wallet=${Backend.pubKey}');
},
child: Text("Recharge"),
width: 250,
color: Colors.blue)),
],
),
Padding(
padding: const EdgeInsets.all(8.0),
child: GlassButton(
onTap: () {
Navigator.of(context).pop();
},
child: Text("Cancel"),
width: 150,
color: Colors.red),
)
],
);
}

83
lib/firebase_options.dart Normal file
View File

@ -0,0 +1,83 @@
// File generated by FlutterFire CLI.
// ignore_for_file: type=lint
import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart'
show defaultTargetPlatform, kIsWeb, TargetPlatform;
/// Default [FirebaseOptions] for use with your Firebase apps.
///
/// Example:
/// ```dart
/// import 'firebase_options.dart';
/// // ...
/// await Firebase.initializeApp(
/// options: DefaultFirebaseOptions.currentPlatform,
/// );
/// ```
class DefaultFirebaseOptions {
static FirebaseOptions get currentPlatform {
if (kIsWeb) {
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for web - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
}
switch (defaultTargetPlatform) {
case TargetPlatform.android:
return android;
case TargetPlatform.iOS:
return ios;
case TargetPlatform.macOS:
return macos;
case TargetPlatform.windows:
return windows;
case TargetPlatform.linux:
throw UnsupportedError(
'DefaultFirebaseOptions have not been configured for linux - '
'you can reconfigure this by running the FlutterFire CLI again.',
);
default:
throw UnsupportedError(
'DefaultFirebaseOptions are not supported for this platform.',
);
}
}
static const FirebaseOptions android = FirebaseOptions(
apiKey: 'AIzaSyDyWHadwDE-CAtMbKfZ7Llq18zGMDPyRpY',
appId: '1:652710461284:android:44b78de76f4d6f88f54471',
messagingSenderId: '652710461284',
projectId: 'sologin-55bbd',
storageBucket: 'sologin-55bbd.firebasestorage.app',
);
static const FirebaseOptions ios = FirebaseOptions(
apiKey: 'AIzaSyC9CtRWl698ntfegoGzdhjQjmpYNNMkTgI',
appId: '1:652710461284:ios:6eee89e45d69a3d1f54471',
messagingSenderId: '652710461284',
projectId: 'sologin-55bbd',
storageBucket: 'sologin-55bbd.firebasestorage.app',
iosClientId: '652710461284-edt1dp5nd7v5k6u0hov8hrq2fkk46bal.apps.googleusercontent.com',
iosBundleId: 'com.xperiencemhuntlauncher.mhuntLauncher',
);
static const FirebaseOptions macos = FirebaseOptions(
apiKey: 'AIzaSyC9CtRWl698ntfegoGzdhjQjmpYNNMkTgI',
appId: '1:652710461284:ios:bae7c085a1ba8dfbf54471',
messagingSenderId: '652710461284',
projectId: 'sologin-55bbd',
storageBucket: 'sologin-55bbd.firebasestorage.app',
iosClientId: '652710461284-7c8o89arbs7aebma2gljgi8iq06f07k6.apps.googleusercontent.com',
iosBundleId: 'com.xperiencemhuntlauncher.mhuntla',
);
static const FirebaseOptions windows = FirebaseOptions(
apiKey: 'AIzaSyCpATgMXv9Pu3coBwljh0uv9I9ciFkBJIA',
appId: '1:652710461284:web:4d52a8a41d1f3ae2f54471',
messagingSenderId: '652710461284',
projectId: 'sologin-55bbd',
authDomain: 'sologin-55bbd.firebaseapp.com',
storageBucket: 'sologin-55bbd.firebasestorage.app',
measurementId: 'G-8NTXQZGV4P',
);
}

View File

@ -14,6 +14,7 @@ import 'package:mhunt_launcher/sidebar.dart';
import 'package:process_run/process_run.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:path/path.dart' as Path;
import 'package:toastification/toastification.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'Backend/DebugHelper.dart';
import 'package:http/http.dart' as http;
@ -47,7 +48,6 @@ class _HomePageState extends State<HomePage> {
int dashboardSelectedGameIndex = 0;
String userPubKey = "loading";
@override
void initState() {
// TODO: implement initState
@ -74,9 +74,24 @@ class _HomePageState extends State<HomePage> {
void initData()async{
userPubKey= await Backend.GetPubkey();
await Backend.GetWalletBalance();
setState(() {
});
Debug.Log("Logged in as " + Backend.Username);
if(Backend.Username.contains(Backend.GUEST_PREFIX)){
Debug.Log("Guest mode on");
toastification.show(
context: context, // optional if you use ToastificationWrapper
title: Text('You are in guest Mode\n Link a social account to secure your login'),
autoCloseDuration: const Duration(seconds: 10),
showIcon: true,
backgroundColor: Colors.amber,
foregroundColor: Colors.red,
icon: Icon(Icons.warning,color: Colors.red,)
);
}
}
void kickstartAnimations() async {

View File

@ -1,5 +1,7 @@
import 'dart:convert';
import 'dart:math';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
@ -29,7 +31,7 @@ class _LoginPageState extends State<LoginPage> {
kickstartAnimations();
//autoLogin();
autoLogin();
}
void autoLogin() async {
@ -145,6 +147,7 @@ class _LoginPageState extends State<LoginPage> {
}
int web3loginState = 0;
String web3id = "";
void loginWeb3() async{
String requestId = await Backend.CreateRequest();
setState(() {
@ -156,8 +159,11 @@ class _LoginPageState extends State<LoginPage> {
await Future.delayed(const Duration(seconds: 1));
requestResponse = await Backend.GetRequestResponse(requestId);
}
Debug.Log("Signing with firebase auth");
web3id = requestResponse;
UserCredential user = await FirebaseAuth.instance.signInWithCustomToken(requestResponse);
Debug.Log(jsonEncode(user.user));
web3id = user.user?.displayName ?? "null";
String dispName = await Backend.GetDisplayName(web3id);
if(dispName == "-1"){
setState(() {
@ -221,10 +227,11 @@ class _LoginPageState extends State<LoginPage> {
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
Text("Username "),
Text("Email address"),
SizedBox(
width: 300,
child: TextField(
@ -261,6 +268,35 @@ class _LoginPageState extends State<LoginPage> {
},
)
], mainAxisAlignment: MainAxisAlignment.center),
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
GlassButton(onTap: ()=>{
HandleExternalLogin("google")
}, color: Colors.green, child: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.g_mobiledata,size: 25,),
Text("Sign in with Google"),
SizedBox()
],
),
), width: 200, height: 40),
GlassButton(onTap: (){}, color: Colors.grey, child: Container(
padding: EdgeInsets.symmetric(horizontal: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Icon(Icons.g_mobiledata,size: 25,),
Text("Sign in with Github"),
SizedBox()
],
),
), width: 200, height: 40)
],
),
GlassButton(onTap: (){setState(() {
isGuest=true;
});}, child: Row(
@ -275,6 +311,31 @@ class _LoginPageState extends State<LoginPage> {
);
}
Future<void> HandleExternalLogin(String provider) async {
String newId = await Backend.CreateNewRequest();
String url = 'https://sologin.playpoolstudios.com/external_auth?provider=${provider}&id=${newId}';
launchUrl(Uri.parse(url));
String requestResponse = "";
while(requestResponse == ""){
await Future.delayed(const Duration(seconds: 1));
requestResponse = (await Backend.GetRequestResponse(newId)).replaceAll(" ", "");
}
UserCredential user = await FirebaseAuth.instance.signInWithCustomToken(requestResponse);
web3id = user.user?.uid ?? "";
String dispName = await Backend.GetDisplayName(web3id);
if(dispName == "-1"){
setState(() {
web3loginState = 2;
});
}else{
usernameEditingController.text = dispName;
completeweb3();
}
}
Widget TraditionalLoginGuest(){
return Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
@ -351,21 +412,28 @@ class _LoginPageState extends State<LoginPage> {
return;
}
String username = await Backend.GetNextGuestUsername();
bool success= await Backend.Register(username, username, gamertagController.text);
if(success){
// String username = Backend.GUEST_PREFIX + await Backend.GetNextGuestUsername();
String username = "";
try {
final userCredential = await FirebaseAuth.instance.signInAnonymously();
username = userCredential.user?.uid ?? "";
}catch(e){
Dialogs.showAlertDialog(context, "Error", e.toString());
}
if(username.length > 2){
bool success= await Backend.Register(username, username, gamertagController.text);
usernameController.text = username;
passwordController.text = username;
OnLoginSuccess();
}
}
void OnLoginSuccess() async{
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('username', usernameController.text);
prefs.setString('password', passwordController.text);
prefs.setString('displayname', Backend.displayName);
Navigator.of(context).push(MaterialPageRoute(builder: (context) => HomePage()));
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (context) => HomePage()));
}
}

View File

@ -1,8 +1,14 @@
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart';
import 'package:mhunt_launcher/checking_update.dart';
import 'package:mhunt_launcher/login.dart';
import 'firebase_options.dart';
void main() {
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
runApp(const MyApp());
}

View File

@ -5,11 +5,15 @@
import FlutterMacOS
import Foundation
import firebase_auth
import firebase_core
import path_provider_foundation
import shared_preferences_foundation
import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin"))
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))

View File

@ -1,6 +1,14 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
_flutterfire_internals:
dependency: transitive
description:
name: _flutterfire_internals
sha256: "71c01c1998c40b3af1944ad0a5f374b4e6fef7f3d2df487f3970dbeadaeb25a1"
url: "https://pub.dev"
source: hosted
version: "1.3.46"
args:
dependency: transitive
description:
@ -113,6 +121,54 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.3"
firebase_auth:
dependency: "direct main"
description:
name: firebase_auth
sha256: "49c356bac95ed234805e3bb928a86d5b21a4d3745d77be53ecf2d61409ddb802"
url: "https://pub.dev"
source: hosted
version: "5.3.3"
firebase_auth_platform_interface:
dependency: transitive
description:
name: firebase_auth_platform_interface
sha256: "9bc336ce673ea90a9dbdb04f0e9a3e52a32321898dc869cdefe6cc0f0db369ed"
url: "https://pub.dev"
source: hosted
version: "7.4.9"
firebase_auth_web:
dependency: transitive
description:
name: firebase_auth_web
sha256: "56dcce4293e2a2c648c33ab72c09e888bd0e64cbb1681a32575ec9dc9c2f67f3"
url: "https://pub.dev"
source: hosted
version: "5.13.4"
firebase_core:
dependency: "direct main"
description:
name: firebase_core
sha256: "2438a75ad803e818ad3bd5df49137ee619c46b6fc7101f4dbc23da07305ce553"
url: "https://pub.dev"
source: hosted
version: "3.8.0"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
sha256: e30da58198a6d4b49d5bce4e852f985c32cb10db329ebef9473db2b9f09ce810
url: "https://pub.dev"
source: hosted
version: "5.3.0"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
sha256: f967a7138f5d2ffb1ce15950e2a382924239eaa521150a8f144af34e68b3b3e5
url: "https://pub.dev"
source: hosted
version: "2.18.1"
fixnum:
dependency: transitive
description:
@ -156,10 +212,10 @@ packages:
dependency: "direct main"
description:
name: http
sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "1.2.2"
http_parser:
dependency: transitive
description:
@ -388,10 +444,10 @@ packages:
dependency: transitive
description:
name: shared_preferences_web
sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a"
sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf
url: "https://pub.dev"
source: hosted
version: "2.3.0"
version: "2.2.1"
shared_preferences_windows:
dependency: transitive
description:
@ -537,10 +593,10 @@ packages:
dependency: transitive
description:
name: url_launcher_web
sha256: "8d9e750d8c9338601e709cd0885f95825086bd8b642547f26bda435aade95d8a"
sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e"
url: "https://pub.dev"
source: hosted
version: "2.3.1"
version: "2.3.3"
url_launcher_windows:
dependency: transitive
description:
@ -577,10 +633,10 @@ packages:
dependency: transitive
description:
name: web
sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
sha256: cd3543bd5798f6ad290ea73d210f423502e71900302dde696f8bff84bf89a1cb
url: "https://pub.dev"
source: hosted
version: "0.5.1"
version: "1.1.0"
win32:
dependency: transitive
description:
@ -606,5 +662,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.3.1 <4.0.0"
flutter: ">=3.19.0"
dart: ">=3.4.0 <4.0.0"
flutter: ">=3.22.0"

View File

@ -45,6 +45,8 @@ dependencies:
url_launcher: ^6.2.6
flutter_spinkit: ^5.2.1
toastification: ^2.3.0
firebase_core: ^3.8.0
firebase_auth: ^5.3.3
dev_dependencies:
flutter_test:

View File

@ -6,9 +6,15 @@
#include "generated_plugin_registrant.h"
#include <firebase_auth/firebase_auth_plugin_c_api.h>
#include <firebase_core/firebase_core_plugin_c_api.h>
#include <url_launcher_windows/url_launcher_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
FirebaseAuthPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FirebaseAuthPluginCApi"));
FirebaseCorePluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
UrlLauncherWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
}

View File

@ -3,6 +3,8 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
firebase_auth
firebase_core
url_launcher_windows
)