refactor message send for consumers

This commit is contained in:
Alexander Karpov 2022-07-03 12:30:36 +03:00
parent 9d4871296a
commit c0dcde9ff3
3 changed files with 72 additions and 83 deletions

View File

@ -13,10 +13,16 @@ from game.models import Deck
from room.models import PlayerInQueue, Room, PlayerInRoom, GameState from room.models import PlayerInQueue, Room, PlayerInRoom, GameState
from room.services.room_create import create_room from room.services.room_create import create_room
channel_layer = get_channel_layer()
class BaseConsumer(AsyncWebsocketConsumer):
def __init__(self, *args, **kwargs):
super().__init__(args, kwargs)
async def send_message(self, message_type: str, **data):
await self.send(text_data=json.dumps({"type": message_type, **data}))
class QueueConsumer(AsyncWebsocketConsumer): class QueueConsumer(BaseConsumer):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(args, kwargs) super().__init__(args, kwargs)
self.room_group_name = None self.room_group_name = None
@ -40,27 +46,17 @@ class QueueConsumer(AsyncWebsocketConsumer):
try: try:
data = json.loads(text_data) data = json.loads(text_data)
except ValueError: except ValueError:
await self.send( await self.send_message("ERROR", message="data is not JSON serializable")
text_data=json.dumps(
{"type": "ERROR", "message": "data is not JSON serializable"}
)
)
if data: if data:
# TODO move to external function/class # TODO move to external function/class
if "type" not in data: if "type" not in data:
await self.send( await self.send_message("ERROR", message="incorrect data typing")
text_data=json.dumps(
{"type": "ERROR", "message": "incorrect data typing"}
)
)
else: else:
if data["type"] == "connect": if data["type"] == "connect":
if "deck_id" not in data: if "deck_id" not in data:
await self.send( await self.send_message(
text_data=json.dumps( "ERROR", message="deck id is not provided"
{"type": "ERROR", "message": "deck id is not provided"}
)
) )
else: else:
deck = None deck = None
@ -69,32 +65,22 @@ class QueueConsumer(AsyncWebsocketConsumer):
deck_id = int(data["deck_id"]) deck_id = int(data["deck_id"])
deck = await self.check_user_deck(deck_id) deck = await self.check_user_deck(deck_id)
except ValueError: except ValueError:
await self.send( await self.send_message(
text_data=json.dumps( "ERROR", message="deck id is incorrect"
{"type": "ERROR", "message": "deck id is incorrect"}
)
) )
if deck: if deck:
# add to que, start finding players # add to que, start finding players
await self.queue_connector(deck) await self.queue_connector(deck)
await self.send( await self.send_message(
text_data=json.dumps( "INFO",
{ message=f"added to queue deck with score {self.scope['score']}",
"type": "INFO",
"message": f"added to queue deck with score {self.scope['score']}",
}
)
) )
opponent = await self.find_user_by_score() opponent = await self.find_user_by_score()
if not opponent: if not opponent:
await self.send( await self.send_message(
text_data=json.dumps( "INFO", message="no user found, awaiting in queue"
{
"type": "INFO",
"message": "no user found, awaiting in queue",
}
)
) )
else: else:
# add to group and send message that opponent found to players # add to group and send message that opponent found to players
@ -116,23 +102,14 @@ class QueueConsumer(AsyncWebsocketConsumer):
}, },
) )
await self.send( await self.send_message(
text_data=json.dumps( "INFO",
{ message=f"user found, with score {opponent[1]}",
"type": "INFO", room=room,
"message": f"user found, with score {opponent[1]}",
"room": room,
}
)
) )
else: else:
await self.send( await self.send_message(
text_data=json.dumps( "ERROR", message="such deck doesn't exist"
{
"type": "ERROR",
"message": "such deck doesn't exist",
}
)
) )
@sync_to_async @sync_to_async
@ -183,24 +160,20 @@ class QueueConsumer(AsyncWebsocketConsumer):
self.scope["score"] = queue.score self.scope["score"] = queue.score
async def info(self, event): async def info(self, event):
message = event["message"]
msg = {"type": "INFO", "message": message}
if "room" in event: if "room" in event:
msg["room"] = event["room"] await self.send_message(
"INFO", message=event["message"], room=event["room"]
await self.send(text_data=json.dumps(msg)) )
else:
await self.send_message("INFO", message=event["message"])
async def check_origin(self): async def check_origin(self):
if not self.scope["player"]: if not self.scope["player"]:
await self.send( await self.send_message("ERROR", message="token is incorrect or expired")
text_data=json.dumps(
{"type": "ERROR", "message": "token is incorrect or expired"}
)
)
await self.close() await self.close()
class RoomConsumer(AsyncWebsocketConsumer): class RoomConsumer(BaseConsumer):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.room_group_name = None self.room_group_name = None
@ -215,18 +188,14 @@ class RoomConsumer(AsyncWebsocketConsumer):
else: else:
message, round = await self.get_state() message, round = await self.get_state()
await self.send( await self.send_message(
json.dumps( "INFO",
{ opponent_score=self.scope["opponent_score"],
"type": "INFO", opponent_deck=self.scope["opponent_deck"],
"opponent_score": self.scope["opponent_score"], opponent_online=self.scope["opponent_online"],
"opponent_deck": self.scope["opponent_deck"], first=self.scope["first"],
"opponent_online": self.scope["opponent_online"], state=message,
"first": self.scope["first"], round=round,
"state": message,
"round": round,
},
)
) )
if "opponent_channel" in self.scope and self.scope["opponent_channel"]: if "opponent_channel" in self.scope and self.scope["opponent_channel"]:
await self.channel_layer.send( await self.channel_layer.send(
@ -315,20 +284,12 @@ class RoomConsumer(AsyncWebsocketConsumer):
try: try:
data = json.loads(text_data) data = json.loads(text_data)
except ValueError: except ValueError:
await self.send( await self.send_message("ERROR", message="data is not JSON serializable")
text_data=json.dumps(
{"type": "ERROR", "message": "data is not JSON serializable"}
)
)
if data: if data:
if data["type"] == "start": if data["type"] == "start":
if not await self.start(data): if not await self.start(data):
await self.send( await self.send_message("ERROR", message="opponent is offline")
text_data=json.dumps(
{"type": "ERROR", "message": "opponent is offline"}
)
)
async def start(self, data): async def start(self, data):
if self.scope["opponent_channel"] and self.scope["opponent_online"]: if self.scope["opponent_channel"] and self.scope["opponent_online"]:

View File

@ -1,7 +1,8 @@
from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models from django.db import models
# Create your models here. # Create your models here.
from game.models import Player, Deck from game.models import Player, Deck, Hero
class PlayerInQueue(models.Model): class PlayerInQueue(models.Model):
@ -48,3 +49,30 @@ class GameState(models.Model):
class Meta: class Meta:
unique_together = ["room", "player", "round"] unique_together = ["room", "player", "round"]
class HeroInGame(models.Model):
hero = models.ForeignKey(Hero, on_delete=models.CASCADE)
player = models.ForeignKey(PlayerInRoom, on_delete=models.CASCADE)
room = models.ForeignKey(Room, on_delete=models.CASCADE)
# state on board
x = models.IntegerField(
blank=False, validators=[MinValueValidator(1), MaxValueValidator(8)]
)
y = models.IntegerField(
blank=False, validators=[MinValueValidator(1), MaxValueValidator(8)]
)
health = models.IntegerField(blank=False)
dead = models.BooleanField(default=False)
def __str__(self):
return f"{self.hero.type} in room {self.room.slug}"
def save(
self, force_insert=False, force_update=False, using=None, update_fields=None
):
if not self.health and not self.dead:
self.health = self.hero.health
super().save(force_insert, force_update, using, update_fields)

View File