fix: matchmaking support start stop, multi connection
This commit is contained in:
parent
6c39a13aca
commit
c02c49215d
@ -14,7 +14,7 @@ class MatchMaking
|
|||||||
this.searching = false;
|
this.searching = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async start(func, mode)
|
async start(receive_func, disconnect_func, mode)
|
||||||
{
|
{
|
||||||
if (!await this.client.isAuthentificate())
|
if (!await this.client.isAuthentificate())
|
||||||
return null;
|
return null;
|
||||||
@ -25,10 +25,21 @@ class MatchMaking
|
|||||||
|
|
||||||
this.searching = true;
|
this.searching = true;
|
||||||
|
|
||||||
|
this.receive_func = receive_func;
|
||||||
|
this.disconnect_func = disconnect_func;
|
||||||
|
|
||||||
this._socket.onmessage = function (event) {
|
this._socket.onmessage = function (event) {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
func(data.game_id)
|
receive_func(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this._socket.onclose = this.onclose.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
onclose(event)
|
||||||
|
{
|
||||||
|
this.stop();
|
||||||
|
this.disconnect_func()
|
||||||
}
|
}
|
||||||
|
|
||||||
async stop()
|
async stop()
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
import { client, navigateTo } from "../index.js";
|
import { client, navigateTo } from "../index.js";
|
||||||
|
import { clear, fill_errors } from "../utils/formUtils.js";
|
||||||
import AbstractView from "./abstracts/AbstractView.js";
|
import AbstractView from "./abstracts/AbstractView.js";
|
||||||
|
|
||||||
function game_found(game_id)
|
|
||||||
{
|
|
||||||
navigateTo(`/games/${game_id}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default class extends AbstractView {
|
export default class extends AbstractView {
|
||||||
constructor(params)
|
constructor(params)
|
||||||
{
|
{
|
||||||
@ -21,28 +17,36 @@ export default class extends AbstractView {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await this.matchmaking();
|
let nb_players = document.getElementById("nb_players-input").value
|
||||||
|
|
||||||
|
await client.matchmaking.start(this.display_data, this.ondisconnect, nb_players);
|
||||||
|
|
||||||
document.getElementById("button").value = "Stop matchmaking"
|
document.getElementById("button").value = "Stop matchmaking"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async matchmaking()
|
ondisconnect()
|
||||||
{
|
{
|
||||||
let nb_players = document.getElementById("nb_players-input").value
|
document.getElementById("button").value = "Find a game"
|
||||||
|
}
|
||||||
|
|
||||||
client.matchmaking.start(game_found, nb_players);
|
display_data(data)
|
||||||
|
{
|
||||||
|
clear("innerText", ["detail"]);
|
||||||
|
fill_errors(data, "innerText");
|
||||||
}
|
}
|
||||||
|
|
||||||
async postInit()
|
async postInit()
|
||||||
{
|
{
|
||||||
document.getElementById("button").onclick = this.matchmaking
|
document.getElementById("button").onclick = this.press_button.bind(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getHtml() {
|
async getHtml() {
|
||||||
return `
|
return `
|
||||||
<h1>Select mode<h1>
|
<h1>Select mode</h1>
|
||||||
<input type="number" value="2" id="nb_players-input">
|
<input type="number" value="2" id="nb_players-input">
|
||||||
<input type="button" value="Find a game" id="button">
|
<input type="button" value="Find a game" id="button">
|
||||||
|
<span id="detail"></span>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,4 +39,4 @@ class MatchMaking(WebsocketConsumer):
|
|||||||
waiting_room: WaitingRoom = normal.get(self.mode)
|
waiting_room: WaitingRoom = normal.get(self.mode)
|
||||||
waiter: Waiter = waiting_room.get_waiter_by_socket(self)
|
waiter: Waiter = waiting_room.get_waiter_by_socket(self)
|
||||||
if (waiter is not None):
|
if (waiter is not None):
|
||||||
waiting_room.remove(self.scope["user"].pk)
|
waiting_room.remove(waiter)
|
@ -10,17 +10,16 @@ class Waiter:
|
|||||||
self.user_id: int = user_id
|
self.user_id: int = user_id
|
||||||
self.socket: WebsocketConsumer = socket
|
self.socket: WebsocketConsumer = socket
|
||||||
|
|
||||||
def send(self, data: dict):
|
def send(self, detail: str, data: dict = {}):
|
||||||
self.socket.send(text_data=json.dumps(data))
|
raw_data: dict = {"detail": detail}
|
||||||
|
raw_data.update(data)
|
||||||
|
self.socket.send(text_data=json.dumps(raw_data))
|
||||||
|
|
||||||
def accept(self):
|
def accept(self):
|
||||||
self.socket.accept()
|
self.socket.accept()
|
||||||
|
|
||||||
def disconnect(self):
|
def disconnect(self):
|
||||||
self.socket.disconnect()
|
self.socket.disconnect(200)
|
||||||
|
|
||||||
def __eq__(self, obj):
|
|
||||||
return self.user_id == obj.user_id
|
|
||||||
|
|
||||||
class WaitingRoom:
|
class WaitingRoom:
|
||||||
|
|
||||||
@ -29,10 +28,10 @@ class WaitingRoom:
|
|||||||
self._mode: int = mode
|
self._mode: int = mode
|
||||||
self._waiting_room_manager = waiting_room_manager
|
self._waiting_room_manager = waiting_room_manager
|
||||||
|
|
||||||
def broadcast(self, data: dict):
|
def broadcast(self, detail: str, data: dict = {}):
|
||||||
for waiter in self._waiter_list:
|
for waiter in self._waiter_list:
|
||||||
waiter: Waiter
|
waiter: Waiter
|
||||||
waiter.send(data)
|
waiter.send(detail, data)
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self._waiter_list.clear()
|
self._waiter_list.clear()
|
||||||
@ -44,20 +43,25 @@ class WaitingRoom:
|
|||||||
return waiter
|
return waiter
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def append(self, waiter: Waiter):
|
def get_waiter_by_user_id(self, user_id: int):
|
||||||
|
for waiter in self._waiter_list:
|
||||||
|
waiter: Waiter
|
||||||
|
if (waiter.user_id == user_id):
|
||||||
|
return waiter
|
||||||
|
return None
|
||||||
|
|
||||||
self.remove(waiter)
|
|
||||||
|
def append(self, waiter: Waiter):
|
||||||
|
tmp: Waiter = self.get_waiter_by_user_id(waiter.user_id)
|
||||||
|
if (tmp is not None):
|
||||||
|
tmp.send("Connection close: Another connection open with the same user id.")
|
||||||
|
self.remove(tmp)
|
||||||
waiter.accept()
|
waiter.accept()
|
||||||
self._waiter_list.append(waiter)
|
self._waiter_list.append(waiter)
|
||||||
|
|
||||||
def remove(self, users_id):
|
def remove(self, waiter: Waiter):
|
||||||
for waiter in self._waiter_list:
|
self._waiter_list.remove(waiter)
|
||||||
waiter: Waiter = waiter
|
waiter.disconnect()
|
||||||
if (waiter == users_id):
|
|
||||||
waiter.disconnect()
|
|
||||||
if (self.empty()):
|
|
||||||
self._waiting_room_manager.remove(self)
|
|
||||||
return
|
|
||||||
|
|
||||||
def empty(self):
|
def empty(self):
|
||||||
for _ in self._waiter_list:
|
for _ in self._waiter_list:
|
||||||
|
41
tournament/consumers.py
Normal file
41
tournament/consumers.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
from channels.generic.websocket import WebsocketConsumer
|
||||||
|
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
from games.models import GameModel
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
from .models import Waiter, WaitingRoom, WaitingRoomManager, normal
|
||||||
|
|
||||||
|
class TournamentWaitingRoom(WebsocketConsumer):
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.channel_name = "tournament"
|
||||||
|
self.group_name = "tournament"
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
|
||||||
|
user: User = self.scope["user"]
|
||||||
|
if (user.is_anonymous or not user.is_authenticated):
|
||||||
|
return
|
||||||
|
|
||||||
|
self.channel_layer.group_add(self.group_name, self.channel_name)
|
||||||
|
|
||||||
|
self.tournament_id = int(self.scope['url_route']['kwargs']['tournament_id'])
|
||||||
|
|
||||||
|
waiting_room: WaitingRoom = normal.get(self.mode)
|
||||||
|
waiting_room.append(Waiter(user.pk, self))
|
||||||
|
|
||||||
|
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):
|
||||||
|
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)
|
Loading…
Reference in New Issue
Block a user