Exemplo n.º 1
0
    def receive(self, text_data):
        text_data_json = json.loads(text_data)
        sender = self.user
        context = text_data_json["context"]

        if context == "request_reject":
            # Treat message as rejecting request
            rtype = text_data_json["type"]

            if rtype == "game" or rtype == "friend":
                req_id = text_data_json["request_id"]
                req_object = UserRequests.objects.filter(id=req_id).first()

                if req_object is None:
                    self.send(text_data=json.dumps({"request_new_ack": "reject_missing"}))
                    return

                if self.user_object != req_object.recipient:
                    self.send(text_data=json.dumps({"request_new_ack": "reject_permission"}))
                    return

                # Reject request
                req_object.answered = True
                req_object.answer = False
                req_object.save()

                # Notify sender and recipient
                self.send(text_data=json.dumps({"request_new_ack": "request_reject", "request_id": req_object.id}))

                # Notify sender that request was rejected
                target_group = "requests_user_" + str(req_object.sender.id)
                req_type = ""

                if req_object.type == "friend":
                    req_type = "o přátelství"
                elif req_object.type == "game":
                    req_type = "o hru"

                async_to_sync(self.channel_layer.group_send)(
                    target_group,
                    {
                        "type": "request_notify_reject",
                        "message": "Tvůj požadavek " + req_type + " s " + req_object.recipient.email + " byl odmítnut",
                        "request_id": req_object.id,
                        "rtype": "friend",
                    }
                )

                return

        # Route based on context
        if context == "request_accept":
            # Treat message as accepting request
            rtype = text_data_json["type"]

            if rtype == "game":
                req_id = text_data_json["request_id"]
                req_object = UserRequests.objects.filter(id=req_id).first()

                # Request doesnt exist
                if req_object is None:
                    self.send(text_data=json.dumps({"request_new_ack": "accept_missing"}))
                    return

                # Request is wrong type
                if req_object.type != "game":
                    self.send(text_data=json.dumps({"request_new_ack": "wrong_type"}))
                    return

                # Block user from accepting request that isnt for him
                if self.user_object != req_object.recipient:
                    self.send(text_data=json.dumps({"request_new_ack": "accept_permission"}))
                    return

                # Get online users
                user_activity_objects = OnlineUserActivity.get_user_activities(timedelta(minutes=3))
                online = (user.user.id for user in user_activity_objects)

                # User is not online
                if not req_object.recipient.id in online:
                    self.send(text_data=json.dumps({"request_new_ack": "not_online"}))
                    return

                # Check if sender is in game
                sending = self.user_object

                if Game.has_active_game(sending):
                    self.send(text_data=json.dumps({"request_new_ack": "already_game_self"}))
                    return

                # Check if recipient is in game
                if Game.has_active_game(req_object.recipient):
                    self.send(text_data=json.dumps({"request_new_ack": "already_game"}))
                    return

                # Create game
                game_object = Game.create_game(req_object.sender, req_object.recipient)

                # Notify players
                target_recipient = "requests_user_" + str(game_object.player1.id)
                target_sender = "requests_user_" + str(game_object.player2.id)

                async_to_sync(self.channel_layer.group_send)(
                    target_recipient,
                    {
                        "type": "request_notify_game",
                        "request_new_ack": "game_start",
                        "game_id": game_object.id,
                    }
                )

                async_to_sync(self.channel_layer.group_send)(
                    target_sender,
                    {
                        "type": "request_notify_game",
                        "request_new_ack": "game_start",
                        "game_id": game_object.id,
                    }
                )

                ann = Announcements()
                ann.text = "Uživatelé " + str(game_object.player1.email) + " a " + str(
                    game_object.player2.email) + " začali hru #" + str(game_object.id) + "."
                ann.save()

                return

            if rtype == "friend":
                req_id = text_data_json["request_id"]
                req_object = UserRequests.objects.filter(id=req_id).first()

                if req_object.type != "friend":
                    self.send(text_data=json.dumps({"request_new_ack": "wrong_type"}))
                    return

                if req_object is None:
                    self.send(text_data=json.dumps({"request_new_ack": "accept_missing"}))
                    return

                if self.user_object != req_object.sender and self.user_object != req_object.recipient:
                    self.send(text_data=json.dumps({"request_new_ack": "accept_permission"}))
                    return

                # Set request responded true and positive
                req_object.answered = True
                req_object.answer = True
                req_object.save()

                # Create friend
                friend = Friends()
                friend.user1 = req_object.sender
                friend.user2 = req_object.recipient
                friend.save()

                # Announcement create
                ann = Announcements()
                ann.text = "Uživatelé " + str(friend.user1.email) + " a " + str(friend.user2.email) + " se stali přáteli."
                ann.save()

                # Notify rejecter to delete his record
                self.send(text_data=json.dumps({"request_new_ack": "request_accept", "request_id": req_object.id}))
                return

        if context == "request_new":
            # Treat message as new request
            rtype = text_data_json["type"]

            # Further route based on type
            if rtype == "game":
                # Treat request as new game request

                # Acknowledge request
                self.send(text_data=json.dumps({"request_new_ack": "acknowledged"}))

                # Get recipient
                id = text_data_json["recipient"]
                recipient = User.objects.filter(id=id).first()
                target_group = "requests_user_" + str(recipient.id)

                # Check if user wants to play game with himself
                if recipient == self.user_object:
                    self.send(text_data=json.dumps({"request_new_ack": "game_self"}))
                    return

                # Get online users
                user_activity_objects = OnlineUserActivity.get_user_activities(timedelta(minutes=3))
                online = (user.user.id for user in user_activity_objects)

                # User is not online
                if not recipient.id in online:
                    self.send(text_data=json.dumps({"request_new_ack": "not_online"}))
                    return

                # Check if recipient have pending request
                if UserRequests.has_pending_request(self.user_object, recipient, rtype):
                    self.send(text_data=json.dumps({"request_new_ack": "already_pending"}))
                    return

                other_side_requests = UserRequests.get_pending_request(recipient, self.user_object, rtype)

                # Check if sender is in game
                sending = self.user_object
                active_game_self = Game.get_active_game(sending)

                if active_game_self is not None:
                    self.send(text_data=json.dumps({"request_new_ack": "already_game_self", "game_id": active_game_self.id}))
                    return

                # Check if recipient is in game
                if Game.has_active_game(recipient):
                    self.send(text_data=json.dumps({"request_new_ack": "already_game"}))
                    return

                # Check pending request from other side
                if len(other_side_requests) > 0:
                    request_object = other_side_requests[0]

                    # Notify other user
                    async_to_sync(self.channel_layer.group_send)(
                        target_group,
                        {
                            "type": "request_notify_merged",
                            "request_new_ack": "merged",
                            "request_id": other_side_requests[0].id,
                            "rtype": "game",
                        }
                    )
                    # Notify self
                    self.send(text_data=json.dumps({
                        "request_new_ack": "merged",
                        "request_id": request_object.id,
                    }))

                    # Set request responded true and positive
                    request_object.answered = True
                    request_object.answer = True
                    request_object.save()

                    # Create game
                    game_object = Game.create_game(request_object.sender, request_object.recipient)

                    # Notify players
                    target_recipient = "requests_user_" + str(game_object.player1.id)
                    target_sender = "requests_user_" + str(game_object.player2.id)

                    async_to_sync(self.channel_layer.group_send)(
                        target_recipient,
                        {
                            "type": "request_notify_game",
                            "request_new_ack": "game_start",
                            "game_id": game_object.id,
                        }
                    )

                    async_to_sync(self.channel_layer.group_send)(
                        target_sender,
                        {
                            "type": "request_notify_game",
                            "request_new_ack": "game_start",
                            "game_id": game_object.id,
                        }
                    )

                    # Terminate rest of function
                    return

                # Actually create Request in database
                request_text = "Uživatel " + self.user + " tě požádal o hru!"
                request = UserRequests.create_request(self.user_object, recipient, "game", request_text)

                # Send request to recipient
                async_to_sync(self.channel_layer.group_send)(
                    target_group,
                    {
                        "type": "request_notify",
                        "message": request_text,
                        'sender_name': self.user,
                        "sender": self.user_id,
                        "request_id": request.id,
                        "rtype": "game",
                    }
                )
                return
            if rtype == "friend":
                # Treat request as new friend request

                # Acknowledge request
                self.send(text_data=json.dumps({"request_new_ack": "acknowledged"}))

                # Get recipient
                id = text_data_json["recipient"]
                recipient = User.objects.filter(id=id).first()
                target_group = "requests_user_" + str(recipient.id)

                # Check if user wants to friend himself
                if recipient == self.user_object:
                    self.send(text_data=json.dumps({"request_new_ack": "friends_self"}))
                    return

                # Check if users are already friends
                if Friends.are_friends(self.user_object, recipient):
                    self.send(text_data=json.dumps({"request_new_ack": "already_friends"}))
                    return

                # Check if recipient have pending request
                if UserRequests.has_pending_request(self.user_object, recipient, rtype):
                    self.send(text_data=json.dumps({"request_new_ack": "already_pending"}))
                    return

                other_side_requests = UserRequests.get_pending_request(recipient, self.user_object, rtype)

                # Check pending request from other side
                if len(other_side_requests) > 0:
                    request_object = other_side_requests[0]

                    # Notify other user
                    async_to_sync(self.channel_layer.group_send)(
                        target_group,
                        {
                            "type": "request_notify_merged",
                            "request_new_ack": "merged",
                            "request_id": other_side_requests[0].id,
                        }
                    )
                    # Notify self
                    self.send(text_data=json.dumps({
                        "request_new_ack": "merged",
                        "request_id": request_object.id,
                    }))

                    # Set request responded true and positive
                    request_object.answered = True
                    request_object.answer = True
                    request_object.save()

                    # Create friend
                    friend = Friends()
                    friend.user1 = self.user_object
                    friend.user2 = recipient
                    friend.save()

                    ann = Announcements()
                    ann.text = "Uživatelé " + str(friend.user1.email) + " a " + str(
                        friend.user2.email) + " se stali přáteli."
                    ann.save()

                    # Terminate rest of function
                    return

                # Actually create Request in database
                request_text = "Uživatel " + self.user + " tě požádal o přátelství!"
                request = UserRequests.create_request(self.user_object, recipient, "friend", request_text)

                # Send request to recipient
                async_to_sync(self.channel_layer.group_send)(
                    target_group,
                    {
                        "type": "request_notify",
                        "message": request_text,
                        'sender_name': self.user,
                        "sender": self.user_id,
                        "request_id": request.id,
                        "rtype": "friend",
                    }
                )