aboutsummaryrefslogtreecommitdiff
path: root/api/game/socket.py
blob: 8bbc951b34dc91c4b7715d2be8803e444f553563 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
from flask import Blueprint, request, make_response
from flask_socketio import SocketIO, emit, Namespace, join_room
from game.voerbak_connector import bord
from auth.login_token import token_login
from db import cursor, connection
import time
import json
from socket_io import io

games = {}


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 user_id != self.player_1_id and user_id != self.player_2_id: 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")
def new_move(data):
	if not data["game_id"] or \
                                  not data["move"] or \
                                  not data["token"]:
		return
	if not data["game_id"] in games: return

	game = games[data["game_id"]]
	if (len(game.board.win_positions) > 0 or game.board.board_full): return
	user_id = token_login(data["token"])
	game.move(user_id, data["move"])


@io.on("resign")
def resign(data):
	if not data["game_id"] or \
                                  not request.cookies.get("token"):
		return
	if not data["game_id"] in games: return

	user_id = token_login(request.cookies.get("token"))
	if not user_id: return

	if games[data["game_id"]].player_1_id != user_id and \
                                  games[data["game_id"]].player_2_id != user_id:
		return

	games[data["game_id"]].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)