Fix rejoining #13

Merged
marco merged 5 commits from fix-rejoining into master 2024-05-21 21:56:36 +00:00
5 changed files with 97 additions and 50 deletions
Showing only changes of commit 358e8a6041 - Show all commits

View File

@ -47,7 +47,7 @@ class GameInfo {
if (playerID == null) return null;
return GameInfo(
playerID: UuidValue.fromString(playerID!), passphrase: phrase);
playerID: UuidValue.fromString(playerID), passphrase: phrase);
}
}

View File

@ -40,23 +40,27 @@ class ServerConnection {
channel!.sink.add(message);
}
void connect(String playerID, String? passphrase) {
if (channel != null) return;
Future? connect(String playerID, String? passphrase) {
if (channel != null) return null;
channel = WebSocketChannel.connect(Uri.parse(config.getWebsocketURL()));
send(
jsonEncode(
WebsocketMessageIdentifyPlayer(
playerID: (playerID),
passphrase: (passphrase),
channel!.ready.then((val) {
send(
jsonEncode(
WebsocketMessageIdentifyPlayer(
playerID: (playerID),
passphrase: (passphrase),
),
),
),
);
);
log(channel!.closeCode.toString());
broadcast = channel!.stream.asBroadcastStream();
broadcast.listen(handleIncomingData);
log(channel!.closeCode.toString());
broadcast = channel!.stream.asBroadcastStream();
broadcast.listen(handleIncomingData);
});
return channel!.ready;
}
Future disconnectExistingConnection() async {

View File

@ -16,24 +16,63 @@ class ConnectionCubit extends Cubit<ConnectionCubitState> {
}
void connect(String playerID, String? passphrase) {
ServerConnection.getInstance().connect(playerID, passphrase);
var connectedFuture =
ServerConnection.getInstance().connect(playerID, passphrase);
connectedFuture?.then((val) {
emit(ConnectionCubitState(
iAmConnected: true,
connectedToPhrase: passphrase,
opponentConnected: false));
});
}
void connectIfNotConnected(String playerID, String? passphrase) {
if (state.iAmConnected && state.connectedToPhrase == passphrase) {
return;
}
if (state.iAmConnected && state.connectedToPhrase != passphrase) {
disonnect().then((val) {
connect(playerID, passphrase);
});
}
connect(playerID, passphrase);
}
Future disonnect() async {
return ServerConnection.getInstance().disconnectExistingConnection();
var disconnectFuture =
ServerConnection.getInstance().disconnectExistingConnection();
disconnectFuture.then(
(val) {
emit(ConnectionCubitState.init());
},
);
return disconnectFuture;
}
void opponentConnected() {
emit(ConnectionCubitState(true));
emit(ConnectionCubitState(
iAmConnected: state.iAmConnected,
connectedToPhrase: state.connectedToPhrase,
opponentConnected: true));
}
}
class ConnectionCubitState {
final bool iAmConnected;
final String? connectedToPhrase;
final bool opponentConnected;
ConnectionCubitState(this.opponentConnected);
ConnectionCubitState(
{required this.iAmConnected,
required this.connectedToPhrase,
required this.opponentConnected});
factory ConnectionCubitState.init() {
return ConnectionCubitState(false);
return ConnectionCubitState(
iAmConnected: false, connectedToPhrase: null, opponentConnected: false);
}
}

View File

@ -33,6 +33,12 @@ class _CreateGameWidgetState extends State<CreateGameWidget> {
disconnectFuture = ConnectionCubit().disonnect();
disconnectFuture.then((val) {
registerResponse = createPrivateGame();
registerResponse.then((val) {
ConnectionCubit().connectIfNotConnected(
val!.playerID.toString(),
val.passphrase,
);
});
});
}
@ -71,12 +77,6 @@ class _CreateGameWidgetState extends State<CreateGameWidget> {
} else {
var passphrase =
snapshot.data?.passphrase ?? "no passphrase";
ConnectionCubit().connect(
snapshot.data!.playerID.toString(),
snapshot.data!.passphrase,
);
return BlocListener<ConnectionCubit,
ConnectionCubitState>(
listener: (context, state) {

View File

@ -3,6 +3,7 @@ import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:http/http.dart' as http;
import 'package:mchess/api/game_info.dart';
import 'package:mchess/connection_cubit/connection_cubit.dart';
@ -19,44 +20,47 @@ class JoinGameHandleWidget extends StatefulWidget {
class _JoinGameHandleWidgetState extends State<JoinGameHandleWidget> {
late Future<GameInfo?> joinGameFuture;
late Future disconnectFuture;
@override
void initState() {
super.initState();
disconnectFuture = ConnectionCubit().disonnect();
disconnectFuture.then((val) {
joinGameFuture = joinPrivateGame(widget.passphrase);
joinGameFuture = joinPrivateGame(widget.passphrase);
joinGameFuture.then((val) {
ConnectionCubit.getInstance().connectIfNotConnected(
val!.playerID!.uuid,
val.passphrase,
);
});
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: disconnectFuture,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return Container();
} else {
return FutureBuilder(
future: joinGameFuture,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const SizedBox(
height: 100,
width: 100,
child: CircularProgressIndicator(),
);
} else {
ConnectionCubit.getInstance().connect(
snapshot.data!.playerID!.uuid,
snapshot.data!.passphrase,
);
var loadingIndicator = const SizedBox(
height: 100,
width: 100,
child: CircularProgressIndicator(),
);
return Scaffold(
body: Center(
child: FutureBuilder(
future: joinGameFuture,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return loadingIndicator;
} else {
return BlocBuilder<ConnectionCubit, ConnectionCubitState>(
builder: (context, state) {
if (state.iAmConnected) {
return const ChessGame();
} else {
return loadingIndicator;
}
});
}
});
}
}),
),
);
}
Future<GameInfo?> joinPrivateGame(String phrase) async {