diff --git a/frontend/static/js/api/chat/channel.js b/frontend/static/js/api/chat/channel.js
index 13c3db6..5b36dd9 100644
--- a/frontend/static/js/api/chat/channel.js
+++ b/frontend/static/js/api/chat/channel.js
@@ -14,7 +14,7 @@ class Channel {
// reload = function to use when we receive a message
async connect(reload) {
- let url = `ws://${window.location.host}/ws/chat/${this.channel_id}/`;
+ let url = `wss://${window.location.host}/ws/chat/${this.channel_id}/`;
this.chatSocket = new WebSocket(url);
this.chatSocket.onmessage = (event) =>{
diff --git a/frontend/static/js/api/matchmaking.js b/frontend/static/js/api/matchmaking.js
index ce0adc8..8dd76e5 100644
--- a/frontend/static/js/api/matchmaking.js
+++ b/frontend/static/js/api/matchmaking.js
@@ -11,18 +11,21 @@ class MatchMaking
* @type {Client}
*/
this.client = client
+ this.searching = false;
}
- async start(func)
+ async start(func, mode)
{
if (!await this.client.isAuthentificate())
return null;
- let url = `wss://${window.location.host}/ws/matchmaking/`;
+ let url = `wss://${window.location.host}/ws/matchmaking/${mode}`;
- this._chatSocket = new WebSocket(url);
+ this._socket = new WebSocket(url);
- this._chatSocket.onmessage = function (event) {
+ this.searching = true;
+
+ this._socket.onmessage = function (event) {
const data = JSON.parse(event.data);
func(data.game_id)
};
@@ -30,7 +33,8 @@ class MatchMaking
async stop()
{
- this._chatSocket.close()
+ this.searching = false;
+ this._socket.close()
}
}
diff --git a/frontend/static/js/views/MatchMakingView.js b/frontend/static/js/views/MatchMakingView.js
index ca02363..01c0522 100644
--- a/frontend/static/js/views/MatchMakingView.js
+++ b/frontend/static/js/views/MatchMakingView.js
@@ -7,18 +7,42 @@ function game_found(game_id)
}
export default class extends AbstractView {
- constructor(params) {
- super(params, "Dashboard");
+ constructor(params)
+ {
+ super(params, "Matchmaking");
+ }
+
+ async press_button()
+ {
+ if (client.matchmaking.searching)
+ {
+ client.matchmaking.stop();
+ document.getElementById("button").value = "Find a game"
+ }
+ else
+ {
+ await this.matchmaking();
+ document.getElementById("button").value = "Stop matchmaking"
+ }
+ }
+
+ async matchmaking()
+ {
+ let nb_players = document.getElementById("nb_players-input").value
+
+ client.matchmaking.start(game_found, nb_players);
}
async postInit()
{
- await client.matchmaking.start(game_found)
+ document.getElementById("button").onclick = this.matchmaking
}
async getHtml() {
return `
-
finding
+ Select mode
+
+
`;
}
diff --git a/games/models.py b/games/models.py
index 0493dc5..514e52c 100644
--- a/games/models.py
+++ b/games/models.py
@@ -5,7 +5,7 @@ class GameModel(models.Model):
finished = models.BooleanField(default=False)
started = models.BooleanField(default=False)
- winner_id = models.IntegerField(null=True, blank=True)
+ winner_id = models.IntegerField(default=-1)
def create(self, users_id: [int]):
self.save()
diff --git a/matchmaking/consumers.py b/matchmaking/consumers.py
index dfa65e8..56b0280 100644
--- a/matchmaking/consumers.py
+++ b/matchmaking/consumers.py
@@ -6,8 +6,7 @@ from games.models import GameModel
import json
-queue_id: [int] = []
-queue_ws: [WebsocketConsumer] = []
+from .models import Waiter, WaitingRoom, WaitingRoomManager, normal
class MatchMaking(WebsocketConsumer):
@@ -24,25 +23,20 @@ class MatchMaking(WebsocketConsumer):
self.channel_layer.group_add(self.group_name, self.channel_name)
- self.accept()
+ self.mode = int(self.scope['url_route']['kwargs']['mode'])
+ self.group_name = self.mode
- global queue_id, queue_ws
- queue_id.append(user.pk)
- queue_ws.append(self)
+ waiting_room: WaitingRoom = normal.get(self.mode)
+ waiting_room.append(Waiter(user.pk, self))
- if len(set(queue_id)) == 2:
- game_id: int = GameModel().create(set(queue_id))
- event = {"game_id": game_id}
- for ws in queue_ws:
- ws.send(text_data=json.dumps({'game_id': game_id}))
- queue_id.clear()
- queue_ws.clear()
+ print(len(waiting_room), "/", self.mode, [len(waiting_room),self.mode])
+ if (len(waiting_room) == self.mode):
+ game_id: int = GameModel().create(waiting_room.get_users_id())
+ waiting_room.broadcast({"detail": "Game found !", "game_id": game_id})
+ waiting_room.clear()
-
def disconnect(self, close_code):
- user: User = self.scope["user"]
- global queue_id, queue_ws
- if (user.pk in queue_id):
- queue_ws.pop(queue_id.index(user.pk))
- queue_id.remove(user.pk)
- self.channel_layer.group_discard(self.group_name, self.channel_name)
\ No newline at end of file
+ waiting_room: WaitingRoom = normal.get(self.mode)
+ waiter: Waiter = waiting_room.get_waiter_by_socket(self)
+ if (waiter is not None):
+ waiting_room.remove(self.scope["user"].pk)
\ No newline at end of file
diff --git a/matchmaking/models.py b/matchmaking/models.py
index 78dda1b..421bef8 100644
--- a/matchmaking/models.py
+++ b/matchmaking/models.py
@@ -1,11 +1,92 @@
from django.db import models
-# Create your models here.
-in_matchmaking = {
- "tournaments": {
+from channels.generic.websocket import WebsocketConsumer
+import json
- },
- "normal": {
-
- }
-}
\ No newline at end of file
+# Create your models here.
+class Waiter:
+
+ def __init__(self, user_id: int, socket: WebsocketConsumer):
+ self.user_id: int = user_id
+ self.socket: WebsocketConsumer = socket
+
+ def send(self, data: dict):
+ self.socket.send(text_data=json.dumps(data))
+
+ def accept(self):
+ self.socket.accept()
+
+ def disconnect(self):
+ self.socket.disconnect()
+
+ def __eq__(self, obj):
+ return self.user_id == obj.user_id
+
+class WaitingRoom:
+
+ def __init__(self, waiting_room_manager, mode: int):
+ self._waiter_list: [Waiter] = []
+ self._mode: int = mode
+ self._waiting_room_manager = waiting_room_manager
+
+ def broadcast(self, data: dict):
+ for waiter in self._waiter_list:
+ waiter: Waiter
+ waiter.send(data)
+
+ def clear(self):
+ self._waiter_list.clear()
+
+ def get_waiter_by_socket(self, socket: WebsocketConsumer):
+ for waiter in self._waiter_list:
+ waiter: Waiter
+ if (waiter.socket is socket):
+ return waiter
+ return None
+
+ def append(self, waiter: Waiter):
+
+ self.remove(waiter)
+ waiter.accept()
+ self._waiter_list.append(waiter)
+
+ def remove(self, users_id):
+ for waiter in self._waiter_list:
+ waiter: Waiter = waiter
+ if (waiter == users_id):
+ waiter.disconnect()
+ if (self.empty()):
+ self._waiting_room_manager.remove(self)
+ return
+
+ def empty(self):
+ for _ in self._waiter_list:
+ return False
+ return True
+
+ def get_users_id(self):
+ return [waiter.user_id for waiter in self._waiter_list]
+
+ def __len__(self):
+ return len(self._waiter_list)
+
+
+
+class WaitingRoomManager:
+
+ def __init__(self):
+ self._waiting_rooms: [WaitingRoom] = []
+
+ def get(self, mode: int):
+ for waiting_room in self._waiting_rooms:
+ waiting_room: WaitingRoom = waiting_room
+ if (waiting_room._mode == mode):
+ return waiting_room
+ tmp: WaitingRoom = WaitingRoom(self, mode)
+ self._waiting_rooms.append(tmp)
+ return tmp
+
+ def remove(self, waiting_room: WaitingRoom):
+ self._waiting_rooms.remove(waiting_room)
+
+normal: WaitingRoomManager = WaitingRoomManager()
\ No newline at end of file
diff --git a/matchmaking/routing.py b/matchmaking/routing.py
index eed5072..417779b 100644
--- a/matchmaking/routing.py
+++ b/matchmaking/routing.py
@@ -2,5 +2,5 @@ from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
- re_path(r'ws/matchmaking/', consumers.MatchMaking.as_asgi())
+ re_path(r'ws/matchmaking/(?P\d+)$', consumers.MatchMaking.as_asgi())
]
diff --git a/tournament/viewset.py b/tournament/viewset.py
index a99caa9..bc27f11 100644
--- a/tournament/viewset.py
+++ b/tournament/viewset.py
@@ -7,7 +7,6 @@ from django.http import HttpRequest
from django.contrib.auth import login
from django.db.models import QuerySet
-from matchmaking.models import in_matchmaking
from .models import TournamentModel
from .serializers import TournamentSerializer