/** * 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)); }
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)); }