118 lines
3.4 KiB
Dart
118 lines
3.4 KiB
Dart
import 'dart:convert';
|
|
import 'dart:developer';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:mchess/api/move.dart';
|
|
import 'package:mchess/api/websocket_message.dart';
|
|
import 'package:mchess/chess_bloc/chess_bloc.dart';
|
|
import 'package:mchess/chess_bloc/chess_events.dart';
|
|
import 'package:mchess/api/register.dart';
|
|
import 'package:mchess/chess_bloc/chess_position.dart';
|
|
import 'package:mchess/connection_cubit/connection_cubit.dart';
|
|
import 'package:mchess/utils/chess_utils.dart';
|
|
import 'package:web_socket_channel/web_socket_channel.dart';
|
|
|
|
class ServerConnection {
|
|
late WebSocketChannel channel;
|
|
late bool wasConnected = false;
|
|
late int counter = 0;
|
|
Stream broadcast = const Stream.empty();
|
|
|
|
static final ServerConnection _instance = ServerConnection._internal();
|
|
|
|
ServerConnection._internal() {
|
|
log("ServerConnection._internal constructor is called");
|
|
}
|
|
|
|
factory ServerConnection() {
|
|
return _instance;
|
|
}
|
|
|
|
factory ServerConnection.getInstance() {
|
|
return ServerConnection();
|
|
}
|
|
|
|
void send(String message) {
|
|
channel.sink.add(message);
|
|
counter++;
|
|
}
|
|
|
|
void connect(String playerID, lobbyID, String? passphrase) {
|
|
if (kDebugMode) {
|
|
channel =
|
|
WebSocketChannel.connect(Uri.parse('ws://localhost:8080/api/ws'));
|
|
} else {
|
|
channel = WebSocketChannel.connect(
|
|
Uri.parse('wss://chess.sw-gross.de:9999/api/ws'));
|
|
}
|
|
send(
|
|
jsonEncode(
|
|
WebsocketMessageIdentifyPlayer(
|
|
playerID: (playerID),
|
|
lobbyID: (lobbyID),
|
|
passphrase: (passphrase),
|
|
),
|
|
),
|
|
);
|
|
|
|
log(channel.closeCode.toString());
|
|
broadcast = channel.stream.asBroadcastStream();
|
|
broadcast.listen(handleIncomingData);
|
|
}
|
|
|
|
void handleIncomingData(dynamic data) {
|
|
log("Data received:");
|
|
log(data);
|
|
var apiMessage = ApiWebsocketMessage.fromJson(jsonDecode(data));
|
|
|
|
switch (apiMessage.type) {
|
|
case MessageType.colorDetermined:
|
|
handleIncomingColorDeterminedMessage(apiMessage);
|
|
break;
|
|
|
|
case MessageType.move:
|
|
handleIncomingMoveMessage(apiMessage);
|
|
break;
|
|
|
|
case MessageType.invalidMove:
|
|
handleInvalidMoveMessage(apiMessage);
|
|
}
|
|
}
|
|
|
|
void handleIncomingColorDeterminedMessage(ApiWebsocketMessage apiMessage) {
|
|
ConnectionCubit.getInstance().opponentConnected();
|
|
ChessBloc.getInstance().add(InitBoard());
|
|
ChessBloc.getInstance().add(
|
|
ColorDetermined(myColor: ChessColor.fromApiColor(apiMessage.color!)));
|
|
}
|
|
|
|
void handleIncomingMoveMessage(ApiWebsocketMessage apiMessage) {
|
|
var move = ChessMove.fromApiMove(apiMessage.move!);
|
|
|
|
if (apiMessage.position != null) {
|
|
ChessBloc.getInstance().add(
|
|
ReceivedMove(
|
|
startSquare: move.from,
|
|
endSquare: move.to,
|
|
position: ChessPositionManager.getInstance()
|
|
.fromPGNString(apiMessage.position!),
|
|
squareInCheck:
|
|
ChessCoordinate.fromApiCoordinate(apiMessage.squareInCheck ?? const ApiCoordinate(col: 0, row: 0)),
|
|
),
|
|
);
|
|
} else {
|
|
log('Error: no position received');
|
|
}
|
|
}
|
|
|
|
void handleInvalidMoveMessage(ApiWebsocketMessage apiMessage) {
|
|
log("invalid move message received, with move: ${apiMessage.move.toString()}");
|
|
ChessBloc.getInstance().add(
|
|
InvalidMovePlayed(
|
|
move: ChessMove.fromApiMove(apiMessage.move!),
|
|
squareInCheck:
|
|
ChessCoordinate.fromApiCoordinate(apiMessage.squareInCheck!),
|
|
),
|
|
);
|
|
}
|
|
}
|