Marco
2a4da9a1af
This adds an option to dragging-and-dropping which is slightly hard on smaller screens. Fix promotions when tapping and fix handling of subsequently tapping two pieces of your color Cancel tap if a drag is started (tapped square will not stay red in case a drag is started) Change url strategy back to the hashtag thing Change version Fix bug that would not allow a piece move if you tried to take an opponents piece. Fix the coloring of the last move after an invalid move was played.
129 lines
3.8 KiB
Dart
129 lines
3.8 KiB
Dart
import 'dart:convert';
|
|
import 'dart:developer';
|
|
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 {
|
|
WebSocketChannel? channel;
|
|
late bool wasConnected = false;
|
|
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) {
|
|
if (channel == null) {
|
|
log("Sending on channel without initializing");
|
|
return;
|
|
}
|
|
channel!.sink.add(message);
|
|
}
|
|
|
|
void connect(String playerID, lobbyID, String? passphrase) {
|
|
String url;
|
|
url = 'wss://chess.sw-gross.de:9999/api/ws';
|
|
channel = WebSocketChannel.connect(Uri.parse(url));
|
|
|
|
send(
|
|
jsonEncode(
|
|
WebsocketMessageIdentifyPlayer(
|
|
playerID: (playerID),
|
|
lobbyID: (lobbyID),
|
|
passphrase: (passphrase),
|
|
),
|
|
),
|
|
);
|
|
|
|
log(channel!.closeCode.toString());
|
|
broadcast = channel!.stream.asBroadcastStream();
|
|
broadcast.listen(handleIncomingData);
|
|
}
|
|
|
|
void disconnectExistingConnection() {
|
|
if (channel == null) return;
|
|
channel!.sink.close();
|
|
}
|
|
|
|
void handleIncomingData(dynamic data) {
|
|
log('${DateTime.now()}: Data received:');
|
|
log(data);
|
|
var apiMessage = ApiWebsocketMessage.fromJson(jsonDecode(data));
|
|
|
|
switch (apiMessage.type) {
|
|
case MessageType.boardState:
|
|
handleBoardStateMessage(apiMessage);
|
|
break;
|
|
|
|
case MessageType.colorDetermined:
|
|
handleIncomingColorDeterminedMessage(apiMessage);
|
|
break;
|
|
|
|
case MessageType.move:
|
|
log('ERROR: move message received');
|
|
break;
|
|
|
|
case MessageType.invalidMove:
|
|
handleInvalidMoveMessage(apiMessage);
|
|
}
|
|
}
|
|
|
|
void handleBoardStateMessage(ApiWebsocketMessage apiMessage) {
|
|
ChessMove? move;
|
|
if (apiMessage.move != null) {
|
|
move = ChessMove.fromApiMove(apiMessage.move!);
|
|
}
|
|
|
|
if (apiMessage.position != null) {
|
|
ChessBloc.getInstance().add(
|
|
ReceivedBoardState(
|
|
startSquare: move?.from,
|
|
endSquare: move?.to,
|
|
position: ChessPositionManager.getInstance()
|
|
.fromPGNString(apiMessage.position!),
|
|
squareInCheck: ChessCoordinate.fromApiCoordinate(
|
|
apiMessage.squareInCheck ??
|
|
const ApiCoordinate(col: 0, row: 0)),
|
|
turnColor: ChessColor.fromApiColor(apiMessage.turnColor!)),
|
|
);
|
|
} else {
|
|
log('Error: no position received');
|
|
}
|
|
}
|
|
|
|
void handleIncomingColorDeterminedMessage(ApiWebsocketMessage apiMessage) {
|
|
ConnectionCubit.getInstance().opponentConnected();
|
|
ChessBloc.getInstance().add(InitBoard());
|
|
ChessBloc.getInstance().add(ColorDetermined(
|
|
myColor: ChessColor.fromApiColor(apiMessage.playerColor!)));
|
|
}
|
|
|
|
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 ?? const ApiCoordinate(col: 0, row: 0)),
|
|
),
|
|
);
|
|
}
|
|
}
|