public async override Task <ValidadeReferenceModel> ValidadeReference(ValidadeReferenceLookuoModel request, ServerCallContext context) { ValidadeReferenceModel output = new ValidadeReferenceModel(); Models.User user = _context.User.FirstOrDefault(u => u.SessionID == request.SessionId); if (user == null) { output.IsItValid = 0; output.BoughtGames = -1; return(await Task.FromResult(output)); } ResponseValidateReference rvr = await APIServerCommunication.validateReference(request.Reference, user.Id); if (rvr.status.Equals("error")) { output.IsItValid = 0; output.BoughtGames = -1; return(await Task.FromResult(output)); } if (rvr.valid.Equals("true")) { // TODO: Executar a transação. String rvtp = await APIServerCommunication.transactionToServerByAccountId(user.Id, request.Reference); if (rvtp.Contains("success")) { // Depois de ser feita a transação, do cliente para o servidor, transforma-se o amount em jogos. Para já, cara crédito pago, corresponde a um jogo. string numberString = new String(rvtp.Where(Char.IsDigit).ToArray()); user.GamesToPlay += Int32.Parse(numberString); _context.SaveChanges(); output.IsItValid = 1; } else { output.IsItValid = 0; } } else { output.IsItValid = 0; } // TODO: Enviar para o cliente os dados do ValidadeReferenceModel, de acordo com aquilo que recebe da API (tem de receber o número de jogos e se é válido) return(await Task.FromResult(output)); }
/** * 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)); }
/** * Registo de novos utilizadores. Devem ser recebidos o username, email e password para criar o novo utilizador. * Quando é guardado um novo utilizador na base de dados, o email e username são transformados em upper case, e * a password é encriptada. */ public async override Task <UserRegistModel> Regist(UserRegistLookupModel request, ServerCallContext context) { UserRegistModel output = new UserRegistModel(); // Transformação dos carateres do email e username para upper case string email = request.Email.ToUpper(); string username = request.Username;//.ToUpper(); // Verificações se um outro utilizador tem o mesmo email e/ou o mesmo username Models.User u1 = new Models.User(), u2 = new Models.User(); u1 = _context.User.FirstOrDefault(u => u.Username == username); u2 = _context.User.FirstOrDefault(u => u.Email == email); // Um utilizador tem o mesmo username if (u1 != null) { if (u2 == null) { output.Valid = -3; // Um utilizador tem apenas o mesmo username } else { output.Valid = -1; // Um utilizador tem o mesmo username e email } } // Um utilizador tem o mesmo email else if (u2 != null) { output.Valid = -2; // Um utilizador tem apenas o mesmo email } // Nenhum utilizador tem o mesmo username e/ou email else { // Encriptação da password SHA512 sha512 = SHA512Managed.Create(); byte[] bytes = sha512.ComputeHash(Encoding.UTF8.GetBytes(request.Password)); string password = Convert.ToBase64String(bytes); Models.User u = new Models.User { Username = username, Email = email, Password = password }; // Verifica e garante que a BD existe _context.Database.EnsureCreated(); // Guarda-se o novo utilizador na base de dados _context.User.Add(u); _context.SaveChanges(); // Regista o utilizador no banco de créditos await APIServerCommunication.RegisterUser(u.Username, u.Id); // Envia-se uma mensagem uma mensagem de confirmação de registo ao cliente output.Valid = 1; } return(await Task.FromResult(output)); }