示例#1
0
        /**
         * Login de utilizadores já existentes. Devem ser recebidos o username e password.
         * Sempre que o login é feito com sucesso, é enviado um ID de sessão único para o cliente
         * que é usado por este para se identificar sempre que envia algum pedido.
         */
        public async override Task <UserLoginModel> Login(UserLoginLookupModel request, ServerCallContext context)
        {
            UserLoginModel output = new UserLoginModel();

            // Transformação de todos os carateres do nome para upper case
            string username = request.Username;//.ToUpper();

            // Encriptação da password
            SHA512 sha512 = SHA512Managed.Create();

            byte[] bytes    = sha512.ComputeHash(Encoding.UTF8.GetBytes(request.Password));
            string password = Convert.ToBase64String(bytes);

            // Verifica-se se o utilizador existe na base de dados e se a password está correta
            Models.User u = _context.User.FirstOrDefault(u => u.Username == request.Username && u.Password == password);

            if (u == null)
            {
                // Se não existir nenhuma entrada na base de dados com o username e password igual, então o output tem de ser autenticação inválida.
                output.Valid     = false;
                output.SessionID = "";
            }
            else
            {
                // Sempre que um utilizador se autentica, é gerado sempre um novo ID de sessão.
                // É usado um ciclo para, no caso do ID de sessão gerado já existir, poder gerar um novo
                bool success;
                do
                {
                    success = true;
                    try
                    {
                        u.GenerateSessionID();
                        _context.SaveChanges();

                        // Altera o id de sessão do cliente, na base de dados da API.
                        await APIServerCommunication.UserLogin(u.SessionID, u.Id);
                    }
                    // Exceção que é lançada sempre que é quebrado o constraint UNIQUE do ID de sessão, no caso do ID de sessão gerado já existir
                    catch (DbUpdateException e) when(e.InnerException is SqlException sqlEx && (sqlEx.Number == 2627 || sqlEx.Number == 2601))
                    {
                        success = false;
                    }
                }while (success == false);

                // Se o login for feito com sucesso, é enviada uma confirmação ao cliente, com o seu ID de sessão
                output.Valid     = true;
                output.SessionID = u.SessionID;
            }

            return(await Task.FromResult(output));
        }
示例#2
0
        public async override Task <PlayModel> Play(PlayLookupModel request, ServerCallContext context)
        {
            PlayModel output = new PlayModel();

            // Obtemos o utilizador da base de dados com o ID de sessão, para depois obtermos o seu ID, se não existir é retornado o código
            // de erro para o cliente
            Models.User user = _context.User.FirstOrDefault(u => u.SessionID == request.SessionId);
            if (user == null)
            {
                output.Result = -1;
                return(await Task.FromResult(output));
            }
            else if (user.GamesToPlay == 0)
            {
                output.Result = -2;
                return(await Task.FromResult(output));
            }

            History h = _context.History.Include(i => i.User).FirstOrDefault(u => u.userId == user.Id);

            if (h == null) // No caso do utilizador nunca ter jogado, criamos uma linha na tabela de estatísticas para este
            {
                _context.Database.EnsureCreated();


                h = new History
                {
                    userId = user.Id,
                    User   = user
                };

                _context.History.Add(h);
                _context.SaveChanges();
            }

            // É gerada a jogada do servidor
            Random rnd        = new Random();
            int    serverPlay = rnd.Next(1, 4);


            switch (request.Play)
            {
            case 1:     // Pedra

                switch (serverPlay)
                {
                case 1:                    // Pedra
                    output.ServerPlay = "Rock";
                    output.Result     = 0; // Empate
                    h.draw++;
                    break;

                case 2:                    // Papel
                    output.ServerPlay = "Paper";
                    output.Result     = 2; // Servidor venceu
                    h.lost++;
                    break;

                case 3:                    // Tesoura
                    output.ServerPlay = "Scissors";
                    output.Result     = 1; // Utilizador venceu
                    h.win++;
                    string result = await APIServerCommunication.transactionFromServerToClient(user.Id, 1);

                    if (!result.Contains("success"))
                    {
                        output.Result = -1;
                        return(await Task.FromResult(output));
                    }
                    break;

                default:
                    break;
                }


                break;

            case 2:     // Papel
                switch (serverPlay)
                {
                case 1:                    // Pedra
                    output.ServerPlay = "Rock";
                    output.Result     = 1; // Utilizador venceu
                    h.win++;
                    string result = await APIServerCommunication.transactionFromServerToClient(user.Id, 1);

                    if (!result.Contains("success"))
                    {
                        output.Result = -1;
                        return(await Task.FromResult(output));
                    }
                    break;

                case 2:                    // Papel
                    output.ServerPlay = "Paper";
                    output.Result     = 0; // Empate
                    h.draw++;
                    break;

                case 3:                    // Tesoura
                    output.ServerPlay = "Scissors";
                    output.Result     = 2; // Servidor venceu
                    h.lost++;
                    break;

                default:
                    break;
                }
                break;

            case 3:     // Tesoura
                switch (serverPlay)
                {
                case 1:                    // Pedra
                    output.ServerPlay = "Rock";
                    output.Result     = 2; // Servidor venceu
                    h.lost++;
                    break;

                case 2:                    // Papel
                    output.ServerPlay = "Paper";
                    output.Result     = 1; // Utilizador venceu
                    h.win++;
                    string result = await APIServerCommunication.transactionFromServerToClient(user.Id, 1);

                    if (!result.Contains("success"))
                    {
                        output.Result = -1;
                        return(await Task.FromResult(output));
                    }
                    break;

                case 3:                    // Tesoura
                    output.ServerPlay = "Scissors";
                    output.Result     = 0; // Empate
                    h.draw++;
                    break;

                default:
                    break;
                }
                break;

            default:
                break;
            }
            user.GamesToPlay--;
            h.Games++;

            _context.SaveChanges();


            return(await Task.FromResult(output));
        }