public override async Task <JoinRoomResponse> JoinRoom(JoinRoomRequest request, ServerCallContext context)
        {
            RedisUserModel user = context.UserState["user"] as RedisUserModel;

            if (user == null)
            {
                return new JoinRoomResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.UNAUTHORIZED)
                       }
            }
            ;

            RedisRoomModel room = await RedisRoomModel.GetRoomFromGuid(request.RoomId);

            if (room == null)
            {
                return new JoinRoomResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.ROOM_DOES_NOT_EXIST)
                       }
            }
            ;

            return(new JoinRoomResponse()
            {
                Status = await room.JoinRoom(user)
            });
        }
        public override async Task <DeleteGameEventResponse> DeleteGameEvent(DeleteGameEventRequest request, ServerCallContext context)
        {
            RedisUserModel user = context.UserState["user"] as RedisUserModel;

            if (user == null)
            {
                return new DeleteGameEventResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.UNAUTHORIZED)
                       }
            }
            ;

            RedisRoomModel room = await RedisRoomModel.GetRoomFromGuid(request.RoomId);

            if (room == null)
            {
                return new DeleteGameEventResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.ROOM_DOES_NOT_EXIST)
                       }
            }
            ;

            return(await room.RemovePlayerGameEvent(user, request.EventId));
        }
        public override async Task <CreateRoomResponse> CreateNewRoom(CreateRoomRequest request, ServerCallContext context)
        {
            RedisUserModel user = context.UserState["user"] as RedisUserModel;

            if (user == null)
            {
                return new CreateRoomResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.UNAUTHORIZED)
                       }
            }
            ;

            // Ensure max players is over 1
            if (request.MaxPlayers < 2)
            {
                return new CreateRoomResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.INVALID_REQUEST)
                       }
            }
            ;


            RedisRoomModel roomModel = new RedisRoomModel(request, user);
            await roomModel.CreateInDatabase();


            return(new CreateRoomResponse()
            {
                CreatedRoom = await roomModel.asRoom(),
                Status = ResponseFactory.createResponse(ResponseType.SUCCESS),
            });
        }
        public override async Task <SubmitGameEventResponse> SubmitGameEvent(SubmitGameEventRequest request, ServerCallContext context)
        {
            RedisUserModel user = context.UserState["user"] as RedisUserModel;

            if (user == null)
            {
                return new SubmitGameEventResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.UNAUTHORIZED)
                       }
            }
            ;

            RedisRoomModel room = await RedisRoomModel.GetRoomFromGuid(request.RoomId);

            if (room == null)
            {
                return new SubmitGameEventResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.ROOM_DOES_NOT_EXIST)
                       }
            }
            ;

            if (!await room.IsPlayerInRoom(user))
            {
                return new SubmitGameEventResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.PERMISSION_DENIED)
                       }
            }
            ;

            return(await room.AddPlayerGameEvent(user, request.EventData));
        }
        public override async Task <GetGameRoomEventsResponse> GetGameRoomEvents(GetGameRoomEventsRequest request, ServerCallContext context)
        {
            RedisUserModel user = context.UserState["user"] as RedisUserModel;

            if (user == null)
            {
                return new GetGameRoomEventsResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.UNAUTHORIZED)
                       }
            }
            ;

            RedisRoomModel room = await RedisRoomModel.GetRoomFromGuid(request.RoomId);

            if (room == null)
            {
                return new GetGameRoomEventsResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.ROOM_DOES_NOT_EXIST)
                       }
            }
            ;

            List <RedisUserModel> playersInGame = await room.GetPlayersInGame();

            if (playersInGame.All(it => it.UserModel.Id != user.UserModel.Id) && !user.HasClaim(UserClaim.Admin))
            {
                return new GetGameRoomEventsResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.PERMISSION_DENIED)
                       }
            }
            ;

            List <GameEventModel> events = await room.GetAllGameEvents();

            // Filter out only the player's events and events that have occurred in the past.
            // Get current tick to determine events in the past.
            GameTick currentTick = new GameTick(DateTime.FromFileTimeUtc(room.RoomModel.UnixTimeStarted), DateTime.UtcNow);

            // Admins see all events :)
            if (!user.HasClaim(UserClaim.Admin))
            {
                events = events.FindAll(it =>
                                        it.OccursAtTick <= currentTick.GetTick() || it.IssuedBy == user.UserModel.Id);
            }

            GetGameRoomEventsResponse response = new GetGameRoomEventsResponse();

            response.GameEvents.AddRange(events);
            response.Status = ResponseFactory.createResponse(ResponseType.SUCCESS);
            return(response);
        }
        public override async Task <GetGroupMessagesResponse> GetGroupMessages(GetGroupMessagesRequest request, ServerCallContext context)
        {
            RedisUserModel user = context.UserState["user"] as RedisUserModel;

            if (user == null)
            {
                return new GetGroupMessagesResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.UNAUTHORIZED)
                       }
            }
            ;

            RedisRoomModel room = await RedisRoomModel.GetRoomFromGuid(request.RoomId);

            if (room == null)
            {
                return new GetGroupMessagesResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.ROOM_DOES_NOT_EXIST)
                       }
            }
            ;

            GroupChatModel groupChat = await room.GetGroupChatById(request.GroupId);

            if (groupChat == null)
            {
                return new GetGroupMessagesResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.CHAT_GROUP_DOES_NOT_EXIST)
                       }
            }
            ;

            if (!groupChat.IsPlayerInGroup(user))
            {
                return new GetGroupMessagesResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.PERMISSION_DENIED)
                       }
            }
            ;

            return(new GetGroupMessagesResponse()
            {
                Status = ResponseFactory.createResponse(ResponseType.SUCCESS),
                Group = await groupChat.asMessageGroup(request.Pagination)
            });
        }
        public override async Task <CreateMessageGroupResponse> CreateMessageGroup(CreateMessageGroupRequest request, ServerCallContext context)
        {
            RedisUserModel user = context.UserState["user"] as RedisUserModel;

            if (user == null)
            {
                return new CreateMessageGroupResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.UNAUTHORIZED)
                       }
            }
            ;

            RedisRoomModel room = await RedisRoomModel.GetRoomFromGuid(request.RoomId);

            if (room == null)
            {
                return new CreateMessageGroupResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.ROOM_DOES_NOT_EXIST)
                       }
            }
            ;

            if (room.RoomModel.RoomStatus != RoomStatus.Ongoing)
            {
                return new CreateMessageGroupResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.PERMISSION_DENIED),
                       }
            }
            ;

            if (!request.UserIdsInGroup.Contains(user.UserModel.Id))
            {
                return new CreateMessageGroupResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.INVALID_REQUEST)
                       }
            }
            ;

            return(await room.CreateMessageGroup(request.UserIdsInGroup.ToList()));
        }
        public override async Task <OpenLobbiesResponse> GetOpenLobbies(OpenLobbiesRequest request, ServerCallContext context)
        {
            RedisUserModel user = context.UserState["user"] as RedisUserModel;

            if (user == null)
            {
                return new OpenLobbiesResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.UNAUTHORIZED)
                       }
            }
            ;

            OpenLobbiesResponse roomResponse = new OpenLobbiesResponse();
            List <Room>         rooms        = (await RedisRoomModel.GetOpenLobbies()).ConvertAll(it => it.asRoom().Result);

            roomResponse.Rooms.AddRange(rooms);
            roomResponse.Status = ResponseFactory.createResponse(ResponseType.SUCCESS);

            return(roomResponse);
        }
        public override async Task <GetMessageGroupsResponse> GetMessageGroups(GetMessageGroupsRequest request, ServerCallContext context)
        {
            RedisUserModel user = context.UserState["user"] as RedisUserModel;

            if (user == null)
            {
                return new GetMessageGroupsResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.UNAUTHORIZED)
                       }
            }
            ;

            RedisRoomModel room = await RedisRoomModel.GetRoomFromGuid(request.RoomId);

            if (room == null)
            {
                return new GetMessageGroupsResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.ROOM_DOES_NOT_EXIST)
                       }
            }
            ;

            List <GroupChatModel> groupChats = await room.GetPlayerGroupChats(user);

            GetMessageGroupsResponse response = new GetMessageGroupsResponse();

            foreach (var groupModel in groupChats)
            {
                response.MessageGroups.Add(await groupModel.asMessageGroup());
            }

            response.Status = ResponseFactory.createResponse(ResponseType.SUCCESS);
            return(response);
        }
        public override async Task <StartGameEarlyResponse> StartGameEarly(StartGameEarlyRequest request, ServerCallContext context)
        {
            RedisUserModel user = context.UserState["user"] as RedisUserModel;

            if (user == null)
            {
                return new StartGameEarlyResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.UNAUTHORIZED)
                       }
            }
            ;

            RedisRoomModel room = await RedisRoomModel.GetRoomFromGuid(request.RoomId);

            if (room == null)
            {
                return new StartGameEarlyResponse()
                       {
                           Status = ResponseFactory.createResponse(ResponseType.ROOM_DOES_NOT_EXIST)
                       }
            }
            ;

            if (room.RoomModel.CreatorId == user.UserModel.Id)
            {
                return(new StartGameEarlyResponse()
                {
                    Status = await room.StartGame(),
                });
            }
            return(new StartGameEarlyResponse()
            {
                Status = ResponseFactory.createResponse(ResponseType.PERMISSION_DENIED),
            });
        }