from flask import Blueprint, request, make_response from flask_socketio import SocketIO, emit, Namespace, join_room from game.voerbak_connector import bord from db import cursor, connection from socket_io import io from hierarchy import io_auth_required import time import json games = {} def participants_only(func): ''' listener should have two parameters: listener(data: socket.io.data, user_id: str, game: game) listener should only be executed if the request comes from one of the game participants (player_1_id | player_2_id) ''' def wrapper(data, user_id): game_id = data["game_id"] if not game_id or \ not game_id in games: return game = games[game_id] if game.player_1_id != user_id and \ game.player_2_id != user_id: return return func(data, user_id, game) wrapper.__name__ = func.__name__ return wrapper class game: def __init__(self, game_id, io, player_1_id, player_2_id): self.game_id = game_id self.room = "game-" + game_id self.board = bord(7, 6) self.io = io self.player_1_id = player_1_id self.player_2_id = player_2_id # drop a disc in `column` def move(self, user_id, column): if len(self.board.win_positions) > 0: return if self.board.board_full: return move = self.player_1_id if self.board.player_1 else self.player_2_id if user_id != move: return self.board.drop_fisje(column) io.emit("fieldUpdate", {"field": self.board.board}, room=self.room) now = int(time.time() * 1000) cursor.execute( "update games set last_activity = ?, moves = moves || ? || ',' where game_id = ?", [now, column, self.game_id] ) connection.commit() if len(self.board.win_positions) > 0 or self.board.board_full: outcome = "d" if not self.board.board_full: winner = self.board.board[int(self.board.win_positions[0][0])] outcome = "w" if winner == "2" else "l" io.emit( "finish", { "winPositions": self.board.win_positions, "boardFull": self.board.board_full }, room=self.room ) self.close("finished", outcome) return io.emit("turnUpdate", {"player1": self.board.player_1}, room=self.room) def resign(self): self.board.kill_voerbak() io.emit("resign", room=self.room) self.close("resign", "d") def close(self, new_status, outcome): cursor.execute( " ".join( [ "update games set", "moves = moves || '0',", "duration = ?,", "status = ?,", "outcome = ?", "where game_id = ?" ] ), [ int(time.time() * 1000) - cursor.execute( "select started from games where game_id = ?", [self.game_id] ).fetchone()[0], new_status, outcome, self.game_id ] ) connection.commit() games.pop(self.game_id) @io.on("newMove") @io_auth_required("none") @participants_only def new_move(data, user_id, game): move = data.get("move") if not move: return game.move(user_id, move) @io.on("resign") @io_auth_required("none") @participants_only def resign(data, user_id, game): game.resign() @io.on("registerGameListener") def register_game_listener(data): game_id = data.get("game_id") if not game_id: return join_room("game-" + game_id)