Compare commits
	
		
			6 Commits
		
	
	
		
			fb1b71ade6
			...
			ae20be25fb
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ae20be25fb | |||
| ad6cfdf08a | |||
| 08ce682980 | |||
| 982130a02f | |||
| 326724930a | |||
| 85787760b9 | 
| @ -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 | ||||||
| ``` | ``` | ||||||
|  | |||||||
| @ -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; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
							
								
								
									
										42
									
								
								frontend/static/js/api/matchmaking.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								frontend/static/js/api/matchmaking.js
									
									
									
									
									
										Normal 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} | ||||||
| @ -8,19 +8,19 @@ class Profile | |||||||
| 		this.user_id = user_id | 		this.user_id = user_id | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	async init(id) | 	async init(user_id) | ||||||
| 	{ | 	{ | ||||||
| 		let response = await this.client._get(`/api/profiles/${id}`); | 		let response = await this.client._get(`/api/profiles/${user_id}`); | ||||||
| 		let response_data = await response.json(); | 		let response_data = await response.json(); | ||||||
|  |  | ||||||
| 		this.id = id; | 		this.user_id = user_id; | ||||||
| 		this.username = response_data.username; | 		this.username = response_data.username; | ||||||
| 		this.avatar_url = response_data.avatar_url; | 		this.avatar_url = response_data.avatar_url; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	async change_avatar(form_data) | 	async change_avatar(form_data) | ||||||
| 	{ | 	{ | ||||||
| 		let response = await this.client._patch_file(`/api/profiles/${this.id}`, form_data); | 		let response = await this.client._patch_file(`/api/profiles/${this.user_id}`, form_data); | ||||||
| 		let response_data = await response.json() | 		let response_data = await response.json() | ||||||
|  |  | ||||||
| 		return response_data; | 		return response_data; | ||||||
|  | |||||||
| @ -33,7 +33,7 @@ const navigateTo = async (uri) => { | |||||||
|         history.pushState(null, null, uri); |         history.pushState(null, null, uri); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const router = async (uri = "") => { | const router = async (uri) => { | ||||||
|     const routes = [ |     const routes = [ | ||||||
|         { path: "/", view: Dashboard }, |         { path: "/", view: Dashboard }, | ||||||
|         { path: "/profiles", view: ProfilesView}, |         { path: "/profiles", view: ProfilesView}, | ||||||
| @ -86,7 +86,7 @@ const router = async (uri = "") => { | |||||||
|     return 0; |     return 0; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| window.addEventListener("popstate", router); | window.addEventListener("popstate", function() {router(location.pathname)}); | ||||||
|  |  | ||||||
| document.addEventListener("DOMContentLoaded", () => { | document.addEventListener("DOMContentLoaded", () => { | ||||||
|     document.body.addEventListener("click", e => { |     document.body.addEventListener("click", e => { | ||||||
|  | |||||||
| @ -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
									
								
							
							
						
						
									
										0
									
								
								games/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										3
									
								
								games/admin.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								games/admin.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | from django.contrib import admin | ||||||
|  |  | ||||||
|  | # Register your models here. | ||||||
							
								
								
									
										6
									
								
								games/apps.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								games/apps.py
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										14
									
								
								games/models.py
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										3
									
								
								games/tests.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | from django.test import TestCase | ||||||
|  |  | ||||||
|  | # Create your tests here. | ||||||
							
								
								
									
										3
									
								
								games/views.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								games/views.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | |||||||
|  | from django.shortcuts import render | ||||||
|  |  | ||||||
|  | # Create your views here. | ||||||
							
								
								
									
										48
									
								
								matchmaking/consumers.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								matchmaking/consumers.py
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										6
									
								
								matchmaking/routing.py
									
									
									
									
									
										Normal 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()) | ||||||
|  | ] | ||||||
| @ -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 | ||||||
| 		) | 		) | ||||||
| 	) | 	) | ||||||
| }) | }) | ||||||
|  | |||||||
| @ -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', | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user