diff --git a/README.md b/README.md
index 69e2f03..0416c0d 100644
--- a/README.md
+++ b/README.md
@@ -22,8 +22,8 @@ pip install -r requirements.txt
```
- Setup database
```
-python manage.py runserver makemigrations profiles
-python manage.py migrate profiles
+python manage.py runserver makemigrations profiles games
+python manage.py migrate profiles games
```
- Start the developpement server
```
diff --git a/frontend/static/js/api/client.js b/frontend/static/js/api/client.js
index 8e7415a..942d9fa 100644
--- a/frontend/static/js/api/client.js
+++ b/frontend/static/js/api/client.js
@@ -1,4 +1,5 @@
import { Account } from "./account.js";
+import { MatchMaking } from "./matchmaking.js";
import { Profile } from "./profile.js";
import { Profiles } from "./profiles.js";
@@ -19,6 +20,7 @@ class Client
this._url = url;
this.account = new Account(this);
this.profiles = new Profiles(this);
+ this.matchmaking = new MatchMaking(this);
this._logged = undefined;
}
diff --git a/frontend/static/js/api/matchmaking.js b/frontend/static/js/api/matchmaking.js
new file mode 100644
index 0000000..b01db49
--- /dev/null
+++ b/frontend/static/js/api/matchmaking.js
@@ -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}
\ No newline at end of file
diff --git a/frontend/static/js/views/MatchMakingView.js b/frontend/static/js/views/MatchMakingView.js
index f079328..9313d24 100644
--- a/frontend/static/js/views/MatchMakingView.js
+++ b/frontend/static/js/views/MatchMakingView.js
@@ -1,13 +1,30 @@
+import { client, navigateTo } from "../index.js";
import AbstractView from "./AbstractView.js";
+function game_found(game_id)
+{
+ navigateTo(`/games/${game_id}`)
+}
+
export default class extends AbstractView {
constructor(params) {
super(params, "Dashboard");
}
+ async postInit()
+ {
+ await client.matchmaking.start(game_found)
+ console.log("start matchmaking")
+ }
+
async getHtml() {
return `
finding
`;
}
+
+ async leavePage()
+ {
+ await client.matchmaking.stop();
+ }
}
\ No newline at end of file
diff --git a/games/__init__.py b/games/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/games/admin.py b/games/admin.py
new file mode 100644
index 0000000..8c38f3f
--- /dev/null
+++ b/games/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
diff --git a/games/apps.py b/games/apps.py
new file mode 100644
index 0000000..1a3efec
--- /dev/null
+++ b/games/apps.py
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class GamesConfig(AppConfig):
+ default_auto_field = 'django.db.models.BigAutoField'
+ name = 'games'
diff --git a/games/models.py b/games/models.py
new file mode 100644
index 0000000..a2d8315
--- /dev/null
+++ b/games/models.py
@@ -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()
\ No newline at end of file
diff --git a/games/tests.py b/games/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/games/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
diff --git a/games/views.py b/games/views.py
new file mode 100644
index 0000000..91ea44a
--- /dev/null
+++ b/games/views.py
@@ -0,0 +1,3 @@
+from django.shortcuts import render
+
+# Create your views here.
diff --git a/matchmaking/consumers.py b/matchmaking/consumers.py
new file mode 100644
index 0000000..dfa65e8
--- /dev/null
+++ b/matchmaking/consumers.py
@@ -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)
\ No newline at end of file
diff --git a/matchmaking/routing.py b/matchmaking/routing.py
new file mode 100644
index 0000000..eed5072
--- /dev/null
+++ b/matchmaking/routing.py
@@ -0,0 +1,6 @@
+from django.urls import re_path
+from . import consumers
+
+websocket_urlpatterns = [
+ re_path(r'ws/matchmaking/', consumers.MatchMaking.as_asgi())
+]
diff --git a/trancendence/asgi.py b/trancendence/asgi.py
index a229228..699b4d8 100644
--- a/trancendence/asgi.py
+++ b/trancendence/asgi.py
@@ -10,7 +10,9 @@ https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/
import os
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.auth import AuthMiddlewareStack
+
import chat.routing
+import matchmaking.routing
from django.core.asgi import get_asgi_application
@@ -20,7 +22,8 @@ application = ProtocolTypeRouter({
'http':get_asgi_application(),
'websocket':AuthMiddlewareStack(
URLRouter(
- chat.routing.websocket_urlpatterns
+ chat.routing.websocket_urlpatterns +
+ matchmaking.routing.websocket_urlpatterns
)
)
})
diff --git a/trancendence/settings.py b/trancendence/settings.py
index 4e89778..4e21503 100644
--- a/trancendence/settings.py
+++ b/trancendence/settings.py
@@ -43,6 +43,8 @@ INSTALLED_APPS = [
'channels',
'daphne',
+ 'matchmaking.apps.MatchmakingConfig',
+ 'games.apps.GamesConfig',
'accounts.apps.AccountsConfig',
'profiles.apps.ProfilesConfig',
'frontend.apps.FrontendConfig',