add: matchmaking

This commit is contained in:
starnakin 2023-12-12 12:06:13 +01:00
parent ad6cfdf08a
commit ae20be25fb
14 changed files with 152 additions and 3 deletions

View File

@ -22,8 +22,8 @@ pip install -r requirements.txt
``` ```
- Setup database - Setup database
``` ```
python manage.py runserver makemigrations profiles python manage.py runserver makemigrations profiles games
python manage.py migrate profiles python manage.py migrate profiles games
``` ```
- Start the developpement server - Start the developpement server
``` ```

View File

@ -1,4 +1,5 @@
import { Account } from "./account.js"; import { Account } from "./account.js";
import { MatchMaking } from "./matchmaking.js";
import { Profile } from "./profile.js"; import { Profile } from "./profile.js";
import { Profiles } from "./profiles.js"; import { Profiles } from "./profiles.js";
@ -19,6 +20,7 @@ class Client
this._url = url; this._url = url;
this.account = new Account(this); this.account = new Account(this);
this.profiles = new Profiles(this); this.profiles = new Profiles(this);
this.matchmaking = new MatchMaking(this);
this._logged = undefined; this._logged = undefined;
} }

View File

@ -0,0 +1,42 @@
import { client, navigateTo } from "../index.js"
class MatchMaking
{
/**
* @param {client} client
*/
constructor(client)
{
/**
* @type {client}
*/
this.client = client
}
async start(func)
{
if (!await this.client.isAuthentificate())
return null;
console.log(func)
this.callback = func
console.log(this.callback)
let url = `wss://${window.location.host}/ws/matchmaking/`;
this._chatSocket = new WebSocket(url);
this._chatSocket.onmessage = function (event) {
const data = JSON.parse(event.data);
console.log(func, data)
func(data.game_id)
};
}
async stop()
{
this._chatSocket.close()
}
}
export {MatchMaking}

View File

@ -1,13 +1,30 @@
import { client, navigateTo } from "../index.js";
import AbstractView from "./AbstractView.js"; import AbstractView from "./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) {
super(params, "Dashboard"); super(params, "Dashboard");
} }
async postInit()
{
await client.matchmaking.start(game_found)
console.log("start matchmaking")
}
async getHtml() { async getHtml() {
return ` return `
<h1>finding<h1> <h1>finding<h1>
`; `;
} }
async leavePage()
{
await client.matchmaking.stop();
}
} }

0
games/__init__.py Normal file
View File

3
games/admin.py Normal file
View File

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

6
games/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class GamesConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'games'

14
games/models.py Normal file
View File

@ -0,0 +1,14 @@
from django.db import models
# Create your models here.
class GameModel(models.Model):
def create(self, users_id: [int]):
self.save()
for user_id in users_id:
GameMembersModel(game_id=self.pk, member_id=user_id)
return self.pk
class GameMembersModel(models.Model):
game_id = models.IntegerField()
member_id = models.IntegerField()

3
games/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

3
games/views.py Normal file
View File

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

48
matchmaking/consumers.py Normal file
View File

@ -0,0 +1,48 @@
from channels.generic.websocket import WebsocketConsumer
from django.contrib.auth.models import User
from games.models import GameModel
import json
queue_id: [int] = []
queue_ws: [WebsocketConsumer] = []
class MatchMaking(WebsocketConsumer):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.channel_name = "matchmaking"
self.group_name = "matchmaking"
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.accept()
global queue_id, queue_ws
queue_id.append(user.pk)
queue_ws.append(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()
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)

6
matchmaking/routing.py Normal file
View File

@ -0,0 +1,6 @@
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/matchmaking/', consumers.MatchMaking.as_asgi())
]

View File

@ -10,7 +10,9 @@ https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/
import os import os
from channels.routing import ProtocolTypeRouter, URLRouter from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack from channels.auth import AuthMiddlewareStack
import chat.routing import chat.routing
import matchmaking.routing
from django.core.asgi import get_asgi_application from django.core.asgi import get_asgi_application
@ -20,7 +22,8 @@ application = ProtocolTypeRouter({
'http':get_asgi_application(), 'http':get_asgi_application(),
'websocket':AuthMiddlewareStack( 'websocket':AuthMiddlewareStack(
URLRouter( URLRouter(
chat.routing.websocket_urlpatterns chat.routing.websocket_urlpatterns +
matchmaking.routing.websocket_urlpatterns
) )
) )
}) })

View File

@ -43,6 +43,8 @@ INSTALLED_APPS = [
'channels', 'channels',
'daphne', 'daphne',
'matchmaking.apps.MatchmakingConfig',
'games.apps.GamesConfig',
'accounts.apps.AccountsConfig', 'accounts.apps.AccountsConfig',
'profiles.apps.ProfilesConfig', 'profiles.apps.ProfilesConfig',
'frontend.apps.FrontendConfig', 'frontend.apps.FrontendConfig',