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; if (playerID == null) return null;
return GameInfo( 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); channel!.sink.add(message);
} }
void connect(String playerID, String? passphrase) { Future? connect(String playerID, String? passphrase) {
if (channel != null) return; if (channel != null) return null;
channel = WebSocketChannel.connect(Uri.parse(config.getWebsocketURL())); channel = WebSocketChannel.connect(Uri.parse(config.getWebsocketURL()));
send( channel!.ready.then((val) {
jsonEncode( send(
WebsocketMessageIdentifyPlayer( jsonEncode(
playerID: (playerID), WebsocketMessageIdentifyPlayer(
passphrase: (passphrase), playerID: (playerID),
passphrase: (passphrase),
),
), ),
), );
);
log(channel!.closeCode.toString()); log(channel!.closeCode.toString());
broadcast = channel!.stream.asBroadcastStream(); broadcast = channel!.stream.asBroadcastStream();
broadcast.listen(handleIncomingData); broadcast.listen(handleIncomingData);
});
return channel!.ready;
} }
Future disconnectExistingConnection() async { Future disconnectExistingConnection() async {

View File

@ -16,24 +16,63 @@ class ConnectionCubit extends Cubit<ConnectionCubitState> {
} }
void connect(String playerID, String? passphrase) { 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 { Future disonnect() async {
return ServerConnection.getInstance().disconnectExistingConnection(); var disconnectFuture =
ServerConnection.getInstance().disconnectExistingConnection();
disconnectFuture.then(
(val) {
emit(ConnectionCubitState.init());
},
);
return disconnectFuture;
} }
void opponentConnected() { void opponentConnected() {
emit(ConnectionCubitState(true)); emit(ConnectionCubitState(
iAmConnected: state.iAmConnected,
connectedToPhrase: state.connectedToPhrase,
opponentConnected: true));
} }
} }
class ConnectionCubitState { class ConnectionCubitState {
final bool iAmConnected;
final String? connectedToPhrase;
final bool opponentConnected; final bool opponentConnected;
ConnectionCubitState(this.opponentConnected); ConnectionCubitState(
{required this.iAmConnected,
required this.connectedToPhrase,
required this.opponentConnected});
factory ConnectionCubitState.init() { 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 = ConnectionCubit().disonnect();
disconnectFuture.then((val) { disconnectFuture.then((val) {
registerResponse = createPrivateGame(); registerResponse = createPrivateGame();
registerResponse.then((val) {
ConnectionCubit().connectIfNotConnected(
val!.playerID.toString(),
val.passphrase,
);
});
}); });
} }
@ -71,12 +77,6 @@ class _CreateGameWidgetState extends State<CreateGameWidget> {
} else { } else {
var passphrase = var passphrase =
snapshot.data?.passphrase ?? "no passphrase"; snapshot.data?.passphrase ?? "no passphrase";
ConnectionCubit().connect(
snapshot.data!.playerID.toString(),
snapshot.data!.passphrase,
);
return BlocListener<ConnectionCubit, return BlocListener<ConnectionCubit,
ConnectionCubitState>( ConnectionCubitState>(
listener: (context, state) { listener: (context, state) {

View File

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