Prévia do material em texto
UNIVERSIDADE PAULISTA Leonardo Aoki – N408CB-0 Lucas Castro – N4235B-7 Matheus Steffens – N449CG9 Fernando Maciel – N456DF4 Bruno Oliveira - D9412B3 Atividades Práticas Supervisionadas (APS) Correio Eletrônico - ProsaMail São Paulo 2021 UNIP Atividades Práticas Supervisionadas (APS) Correio Eletrônico - ProsaMail Trabalho apresentado ao Curso de Ciências da Computação da Universidade Paulista, como requisito parcial para obtenção da nota de trabalho em APS. Orientador: Arthur Battaglia São Paulo 2021 RESUMO O objetivo foi o desenvolvimento de uma ferramenta para comunicação em rede, que envolva aplicação da ferramenta à preservação ambiental, por isso, decidimos contextualizar historicamente o envio de mensagens antes da criação, como eram feitos os processos de comunicação antigamente e sua evolução histórica até os dias de hoje. O ProsaMail foi criado para facilitar o envio de mensagens de correio eletrônico, de modo que não exista mais o consumo de papel para envio de cartas, como eram feitos no passado. Pensando assim, conciliamos a atividade de preservação ambiental relacionada a controle de consumo de papel, agregado ao meio ambiente. Palavras-chave: comunicação, correio, papel ABSTRACT The objective was the development of a tool for network communication, which involves application of the tool to environmental preservation. Therefore, we decided to historically contextualize the sending of messages before creation, how communication processes were done in the past and their historical evolution until the nowadays. ProsaMail was created to facilitate the sending of e-mail messages, so that there is no more consumption of paper for sending letters, as they were done in the past. With this in mind, we reconcile the activity of environmental preservation related to the control of consumption of paper, added to the environment. Keywords: communication, e-mail, paper SUMÁRIO 1 INTRODUÇÃO....................................................................................................... 6 2 FUNDAMENTOS DA COMUNICAÇÃO DE DADOS EM REDE........................... 7 2.1 COMUNICAÇÃO DE CORREIO ELETRÔNICO..........................................7 2.2 COMUNICAÇÃO DE DADOS.............................................................................7 2.3 SINCRONIZAÇÃO DE DADOS........................................................................9 3 DESENVOLVIMENTO DA APLICAÇÃO.............................................................. 9 4. PROJETO DO PROGRAMA (BANCO)................................................................14 5 APRESENTAÇÃO DO PROGRAMA.................................................................. 15 5.1 CÓDIGO-FONTE........................................................................................15 6 CONSIDERAÇÕES FINAIS................................................................................. 75 REFERÊNCIAS.......................................................................................................... 76 6 1 INTRODUÇÃO A comunicação sempre foi presente em nossa sociedade, porém, ao longo dos anos houve uma evolução positiva nas questões tecnológicas, a humanidade sempre se comunicou de forma natural antes da fase de inovação, os meios para enviar seus comunicados eram cartas, que consequentemente é prejudicial ao meio ambiente pois demanda alta taxa de utilização do papel, automaticamente influenciam no desmatamento de árvores que foi considerado um dos principais Objetivos de Desenvolvimento Sustentável (ODS) da ONU para reduzir nos próximos anos. O sistema de correio eletrônico surgiu com o objetivo de reduzir a quantidade de cartas enviadas por correio comum, pensando no meio ambiente e em um viés de inovação, implantamos a solução do ProsaMail, aplicativo de troca de mensagens que permite enviar comunicados a seus contatos onde quer que estejam. Outros aplicativos como Gmail, Outlook e outras plataformas de troca de mensagens que são usadas no dia a dia, fazem com que ninguém mais se preocupe com a parte ecológica do gasto do papel como parte de envio de mensagens, por isso o ProsaMail se inspirou nessas plataformas e adaptamos o logotipo para conciliar duas vertentes que são importantes para a sociedade, são elas: Comunicação e Meio Ambiente. Relacionando os contextos de Comunicação e Meio ambiente, obtivemos evidências sobre preservação ambiental diretamente ligado ao consumo de papel na pandemia, de acordo com a Papelaria Matriz, teve um aumento de 20% nas vendas de papéis especiais para convites, sulfite e derivados relacionados a comunicação e envio de mensagens pessoalmente, sendo que poderiam ser realizados virtualmente economizando o consumo exagerado de papel. 7 2 FUNDAMENTOS DA COMUNICAÇÃO DE DADOS EM REDE A área de Redes de comunicação de dados concentra grande parte da tecnologia envolvendo Informação e Transmissão, por isso, alguns pontos são considerados em momentos de unir e compartilhar recursos (networking), esse processo acontece como forma de conexão de computadores, seja acesso à programas, compartilhamento de informações ou comunicações pessoais via correio eletrônico. 2.1 COMUNICAÇÃO DE CORREIO ELETRÔNICO A ferramenta de correio eletrônico serve para compartilhar informações, mensagens e arquivos entre pessoas, a fim de passar resposta ao usuário de forma prática e eficiente. 2.2 COMUNICAÇÃO DE DADOS Uma área de Ciências da Computação que é responsável pela transmissão de informação entre sistemas e dispositivos distintos, é relacionado com a passagem de sinal de forma física (cabos) que representam as redes. A Teoria das Redes é baseada no conjunto de dispositivos eletrônicos que são interligados pelo sistema de comunicação com o objetivo compartilhar informações, dados, entre outros serviços. As redes estão diretamente ligadas a comunicação de dados, pois são esses cabos que passam o sinal para dispositivos e assim forma a comunicação de dados. Um dos meios de comunicação é a Internet, que por sua vez é considerado um dos sistemas de comunicação mais utilizado de todos os tempos, é capaz de conectar diversas redes de computadores através de um servidor e compartilhar informações caso o dispositivo contenha meios de acesso, protocolos e segurança. 8 Na forma física de redes, utilizamos os Soquetes de Rede para representar a parte final do fluxo de comunicação através de redes de computadores, esses soquetes são entradas para os fios da internet, popularmente conhecido como “ Cabo de Rede. ” Representando a imagem do processo de aplicação do cabo e o processo: Na imagem, é possível visualizar o TCP/IP, que é um conjunto de protocolos de comunicação entre computadores em rede, a sigla TCP significa Protocolo de Controle de Transmissão, sua função é estabelecer que os dados transmitidos sejam enviados corretamente ao host de destino, por isso, o processo é feito da seguinte maneira, os dados são quebrados em blocos menores de informação e em seguida são recompostos no host do destino. O IP é o Protocolo de Internet, é responsável pela comunicação de hosts de rede, por isso, é feito uma definição de cenário de transmissão e em seguida administra o transporte da mensagem do host origem ao destino. 9 Existem 3 características que são levadas em consideração pela avaliação do sistema em relação ao serviço de host origem e destino: Entrega – Recebidos apenas pelo usuário destino (Exemplo: sistema entregauma mensagem ao usuário) Confiabilidade – Casos de dados corrompidos ou que não foram entregues pelo sistema Tempo – Demora de entregar os dados, seja mensagens ou arquivos em um correio eletrônico. 2.3 SINCRONIZAÇÃO DE DADOS A sincronização é um tipo de gerenciamento envolvendo processos automáticos, como alguma atualização de software ou de dados/arquivos. São classificações de sincronização que acontecem por meio de transmissão: Transmissão Assíncrono- Na transmissão Assíncrono os dados são enviados um a um sem controle de tempo entre um e outro, alguma características deles são: Rendimento curto / Fácil Implementação / Velocidade Baixa 3 DESENVOLVIMENTO DA APLICAÇÃO O projeto foi desenvolvido em linguagem C# através da IDE Visual Studio 2019. Sua arquitetura baseia-se no padrão Model-View-Controller (MVC). O módulo de visualização (View) é dividido em Cliente e Servidor onde, a divisão Cliente possui acesso de seus e-mails e mensagens particulares após realizar um cadastro simples, com usuário e senha. Já a divisão Servidor conta também com um cadastro básico de usuário e senha, porém este não possui acesso a dados particulares, somente habilita ou desabilita o ambiente que permite a troca de mensagens e e-mails entre os usuários cadastrados. 10 Em sua versão Cliente, temos como tela inicial um simples WinForm para realização do login. O botão Entrar faz com que a aplicação inicie uma verificação sobre a existência ou ausência do usuário informado no banco de dados verificando também se a senha é válida. Senha esta que, ao ser cadastrada, passa por um método de criptografia para que não seja acessada diretamente por querys no banco de dados por exemplo. 11 O botão cadastrar permite que o usuário crie sua conta com dados básicos verificando se o usuário informado já existe no banco de dados ou se a senha segue as regras do padrão de senha. Após verificar o usuário e senha com sucesso, a aplicação exibe sua tela principal para a versão Cliente onde o usuário possui acesso aos seus e-mails, ao lado esquerdo e suas mensagens particulares ao lado direito. Disponibiliza também a função de busca onde, o conteúdo digitado, procura correspondências tanto na lista de e-mails como também, na lista de mensagens existentes. Na parte superior temos a barra de botões para facilitar o acesso a determinados tipos de informação como Caixa de entrada, Spam e Lixeira para as rotinas de e-mail e Nova prosa ou editar perfil para as rotinas de mensagens particulares. O usuário pode também iniciar a criação de um novo email ao clicar no botão novo, onde uma nova tela será apresentada. 12 Ao clicar no botão “Nova prosa” um novo WinForm é apresentado ao usuário, contendo uma lista de usuários que se cadastraram em nossa aplicação. Futuramente, implementaremos uma mudança na forma como os contatos serão gerenciados e cada usuário terá sua própria lista de contatos. O módulo controlador (Controller) é o responsável por gerenciar todas as regras de negócio da aplicação. Gerencia regras como a verificação de usuário já existente, senha inválida ou incorreta, receber dados digitados pelo usuário e enviar a solicitação de acesso ao banco de dados, criptografia e descriptografia de senha, verificação de endereço de email existente, buscar lista de usuários cadastrados, receber o conteúdo das 13 mensagens e e-mails, destinar estes conteúdos ao seu devido destinatário, checagem de envio do email ou da mensagem, recebimento de novas mensagens e e-mails, gerenciamento dos sockets que permitem o tráfego de mensagens e e-mails entre dois clientes, entre outras funções. De modo geral, o motor de nossa aplicação será todo inserido no módulo Controller. O módulo modelador (Model) será responsável por gerenciar como as entidades da aplicação devem ser cadastradas, seguindo as regras das tabelas do banco de dados. Nele teremos as classes de usuários, servidores, mensagens, e- mails e contatos, cada um com sua lista de propriedades bem definidas e integradas entre si. Cada usuário cadastrado, servidor, mensagem, email recebido, email enviado ou contato, terá seu objeto instanciado com base nos atributos existentes em sua respectiva classe na camada modeladora, sendo transferido para a controller identificar se fará ou não sua gravação no banco de dados ou somente suas tratativas nas regras de negócio. Não menos importante, teremos a classe DAO, que apesar de não ser considerada como um módulo em nossa aplicação, terá sua divisão bem definida e será responsável por realizar a comunicação direta com o banco de dados. Através dela, realizaremos consultas, atualizações, inserções e exclusões que foram solicitadas por métodos controladores. 14 4. PROJETO DO PROGRAMA (BANCO) Utilizamos o SQL Server para criação de tabelas que serão utilizadas na API do aplicativo, porém, antes de criar as tabelas estabelecemos um servidor Cloud pela AWS (Amazon Web Services, Inc.). Nela Criamos um VPC (Virtual Private Cloud) com uma Subnet Pública e outra Privada, aonde ambas servem para ser um segmento de um intervalo de endereços IP da VPC, onde é possível dispor grupos de recursos isolados. A Pública possui um Internet Gateway que permite fazer uma conexão com a internet enquanto a Privada possui uma NAT Gateway um serviço de Network Address Translation que é gerenciado e altamente disponível para recursos em uma sub-rede privada para acesso à Internet. A VPC em si, possui um grupo de segurança, aonde nele, é permitido a conexão do usuário de fora para dentro da VPC, permitindo, consequentemente, estabelecer uma ponte com o Servidor. Após o estabelecimento da VPC, utilizamos o serviço RDS (Relational Database Service) da AWS, nele, foi criado um Database chamado de “db-faculdade” que utliza todos os tópicos citados anteriormente, aonde as especificações utilizadas foram de 1 processador (vCPUSs) e 1 gigabyte de memória RAM, com armazenamento de 20 GiB de SSD. Após criarmos todo procedimento inicial, e executarmos o Banco de Dados, com o SQL Management Studio 2019 fizemos a conexão com o servidor. Dentro do Banco de dados, foram criados as tabelas Usuario, Mensagem, Email, Chat de Mensagem e Contatos para serem utilizadas pela API para armazenagem de dados. Cade uma dessas tabelas foram estabelecidas as chaves primárias, chaves estrangeiras, os campos não nulos e o tipo de dado que será inserido dentro dela (VARHCHAR, CHAR, INT, ETC...). Após tudo isso ser estabelecido, a API já pode formar uma conexão com o banco de dados e começar a utilização. 15 5 APRESENTAÇÃO DO PROGRAMA O ProsaMail é um sistema de correio eletrônico que realiza troca de mensagens entre usuários, permite visualizar, receber e enviar comunicados a seus contatos onde quer que estejam, cadastrar usuários na sua base de contatos e muito mais serviços. 5.1 CÓDIGO-FONTE 1. Classe de acesso ao Banco de dados a. DbProsaContext.cs Classe que define quais são as entidades (repositórios específicos) existentes na aplicação e instancia uma nova conexão abstrata com o banco de dados, a fim de identificar se existe ou não conexão com o mesmo para que a aplicação possa ser iniciada. b. Repositórios i. EmailRepositorio.cs Classe responsável por buscar no banco de dados as configurações de email do usuário que efetuou o login no sistema, preenchendo um novo objeto de sua respectiva classe (model). Objeto este que é repassado ao Form principal para sua manipulação e personalização dos componentes em tela. ii. UsuarioRepositorio.cs Assim como a classe anterior, possui a mesma função, tendo também sua respectiva classe modeladora que é preenchida com as informações coletadas do banco de dados,criando assim, um novo objeto chamado Usuário. Neste objeto temos seu Id, Id da configuração de e-mail correspondente, senha e outras informações. 16 2. Controllers a. LoginController.cs A LoginController faz a ligação entre a classe de nosso Form principal e a classe que busca as informações no banco de dados. Porém, específicamente referente aos dados de login do usuário. Aqui, a senha e o nome do usuário, que foram digitados no Form de Login ou no Form de Cadastro, são recepcionados e comparados com os dados existentes no banco de dados. Caso os dados correspondam, o login acontece, caso contrário, uma mensagem é apresentada informando o mesmo de que deve corrigir os dados informados. 3. Forms(Telas) a. ConfigEmail.cs Neste WinForm, o usuário pode cadastrar os dados de seu provedor de email, que momentâneamente deve ser exclusivamente Gmail. Email e senha devem ser informados aqui para que possa ser feita a autenticação nos servidores da Google e permitir acessos aos emails. b. Principal.cs Se não houve a classe Program, estaríamos diante do coração do Sistema. Responsável por gerenciar emails recebidos, emails enviados, mensagens enviadas, mensagens recebidas, informar ao usuário qual conta está logada no momento e exibir o conteúdos dos emails. Esta é a classe onde grande parte das regras de negócio é iniciada e gerenciada. c. NovoEmail.cs Tela e classe simples, com poucos campos a serem preenchidos e métodos a serem executados. Basicamente, recebe o assunto, destinatário e corpo do email, válida se as informações são válidas e realiza seu envoi ao servidor SMTP. 4. ChatServidor.cs Classe que instancia o servidor, gerencia e atualiza em tempo real todas as mensagens que entram ou saem, do grupo ao qual o usuário se encontra conectado. É aqui que um listener permanece a todo tempo, verificando novas mensagens e as envia ao Form Principal. 17 5. Program.cs Por fim temos o coração da aplicação. É ela a primeira classe iniciada, onde os primeiros objetos são instanciados e as primeiras verificações são realizadas. Verifica se existe um login efetuado. Caso não exista, a tela de login é exibida, caso contrário, exibe uma MessageBox informando que o Sistema já está em execução. 6. Classes de acesso ao Banco de dados a. DbProsaContext.cs using ProsaMail.Entidades; using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ProsaMail.ContextoDAL { public class DbProsaContext : DbContext { public DbProsaContext() : base("stringConnection") { } public DbSet<Usuario> Usuario { get; set; } public DbSet<Email> Email { get; set; } } } b. Repositórios i. IRepositorio.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ProsaMail.ContextoDAL.Repositorios.Base { interface IRepositorio<TEntity> where TEntity : class { IQueryable<TEntity> GetAll(); IQueryable<TEntity> Get(Func<TEntity, bool> predicate); TEntity Find(params object[] key); void Atualizar(TEntity obj); void Adicionar(TEntity obj); 18 void Excluir(Func<TEntity, bool> predicate); void SalvarTodos(); } } ii. Repositorio.cs using ProsaMail.Entidades; using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ProsaMail.ContextoDAL.Repositorios.Base { public abstract class Repositorio<TEntity> : IDisposable, IRepositorio<TEntity> where TEntity : class { DbProsaContext ctx = new DbProsaContext(); public IQueryable<TEntity> GetAll() { return ctx.Set<TEntity>(); } public IQueryable<TEntity> Get(Func<TEntity, bool> predicate) { return GetAll().Where(predicate).AsQueryable(); } public TEntity Find(params object[] key) { return ctx.Set<TEntity>().Find(key); } public void Atualizar(TEntity obj) { ctx.Entry(obj).State = EntityState.Modified; } public void SalvarTodos() { ctx.SaveChanges(); } public void Adicionar(TEntity obj) { ctx.Set<TEntity>().Add(obj); 19 } public void Excluir(Func<TEntity, bool> predicate) { ctx.Set<TEntity>() .Where(predicate).ToList() .ForEach(del => ctx.Set<TEntity>().Remove(del)); } public void Dispose() { ctx.Dispose(); } } } iii. Email.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ProsaMail.Entidades { public class Email { public int EmailID { get; set; } public string Email_name { get; set; } public string Password { get; set; } public string Host_Name { get; set; } public DateTime Email_date { get; set; } public string Email_content { get; set; } } } iv. Usuario.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ProsaMail.Entidades { public class Usuario { public int UsuarioID { get; set; } 20 public string User_login { get; set; } public string User_senha { get; set; } public string User_name { get; set; } public int Msg_ID { get; set; } public int Email_ID { get; set; } public int ChatMsg_ID { get; set; } public int Contatos_ID { get; set; } } } v. EmailRepositorio.cs using ProsaMail.ContextoDAL.Repositorios.Base; using ProsaMail.Entidades; using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ProsaMail.ContextoDAL.Repositorios { class EmailRepositorio : Repositorio<Email> { private DbProsaContext _db; public EmailRepositorio() { _db = new DbProsaContext(); } public Email AdicionarEmail(Email obj, Usuario usu) { using (DbProsaContext con = new DbProsaContext()) { try { con.Database.Connection.Open(); con.Email.Add(obj); con.SaveChanges(); usu.Email_ID = obj.EmailID; new UsuarioRepositorio().AtualizarEmailUsuario(usu); } catch (Exception erro) { throw erro; } } 21 return obj; } public void AtualizarEmail(Email obj) { using (DbProsaContext con = new DbProsaContext()) { con.Entry(obj).State = EntityState.Modified; } } public void DisposeEmail() { using (DbProsaContext con = new DbProsaContext()) { con.Dispose(); } } public void ExcluirEmail(Func<Email, bool> predicate) { using (DbProsaContext con = new DbProsaContext()) { con.Email.Where(predicate).ToList().ForEach(del => con.Email.Remove(del)); } } public IQueryable<Email> GetEmail(Func<Email, bool> predicate) { return GetAll().Where(predicate).AsQueryable();} public void SalvarTodosEmails() { using (DbProsaContext con = new DbProsaContext()) { con.SaveChanges(); } } public Email FindConfigEmail(Usuario usu) { try { Email objEmail = new Email(); using (DbProsaContext con = new DbProsaContext()) { con.Database.Connection.Open(); var configEmail = con.Email.Where(a => a.EmailID == usu.Email_ID); 22 if (configEmail != null && configEmail.Count() > 0) { objEmail = configEmail.First(); } return objEmail; } } catch (Exception erro) { throw erro; } } public List<Email> GetAllUsers() { List<Email> lista = new List<Email>(); using (DbProsaContext con = new DbProsaContext()) { con.Database.Connection.Open(); var selec = con.Email.Select(a => a); if (selec != null && selec.Count() > 0) { lista = selec.ToList(); } return lista; } } } } 23 vii. UsuarioRepositorio.cs using ProsaMail.ContextoDAL.Repositorios.Base; using ProsaMail.Entidades; using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ProsaMail.ContextoDAL.Repositorios { class UsuarioRepositorio : Repositorio<Usuario> { private DbProsaContext _db; public UsuarioRepositorio() { _db = new DbProsaContext(); } public Usuario AdicionarUsuario(Usuario obj) { using (DbProsaContext con = new DbProsaContext()) { try { con.Database.Connection.Open(); con.Usuario.Add(obj); con.SaveChanges(); } catch (Exception erro) { throw erro; } } return obj; } public void AtualizarEmailUsuario(Usuario obj) { try { using (DbProsaContext con = new DbProsaContext()) { var result = con.Usuario.SingleOrDefault(b => b.UsuarioID == obj.UsuarioID); 24 if (result != null) { result.Email_ID = obj.Email_ID; con.SaveChanges(); } } } catch (Exception erro) { throw erro; } } public void DisposeUsuario() { using (DbProsaContext con = new DbProsaContext()) { con.Dispose(); } } public void ExcluirUsuario(Func<Usuario, bool> predicate) { using (DbProsaContext con = new DbProsaContext()) { con.Usuario.Where(predicate).ToList().ForEach(del => con.Usuario.Remove(del)); } } public Usuario FindUsuario(Usuario usu) { using (DbProsaContext con = new DbProsaContext()) { con.Database.Connection.Open(); con.Usuario.First(c => c.User_login == c.User_login); } return usu; } public IQueryable<Usuario> GetUsuario(Func<Usuario, bool> predicate) { return GetAll().Where(predicate).AsQueryable(); } public void SalvarTodosUsuarios() { using (DbProsaContext con = new DbProsaContext()) { con.SaveChanges(); } 25 } public Usuario FindLogin(Usuario usu) { try { using (DbProsaContext con = new DbProsaContext()) { con.Database.Connection.Open(); var usuarios = con.Usuario.Where(a => a.User_login == usu.User_login); if (usuarios != null && usuarios.Count() > 0) { usu = usuarios.First(); } return usu; } } catch (Exception erro) { throw erro; } } public List<Usuario> GetAllUsers() { List<Usuario> lista = new List<Usuario>(); using (DbProsaContext con = new DbProsaContext()) { con.Database.Connection.Open(); var selec = con.Usuario.Select(a => a); if (selec != null && selec.Count() > 0) { lista = selec.ToList(); } return lista; } } } } 26 7. Controllers a. ContatosController.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using ProsaMail.Entidades; using ProsaMail.ContextoDAL.Repositorios; using System.Data; namespace ProsaMail.Controller { class ContatosController { public List<Usuario> listaTodos_Usuarios() { List<Usuario> listaUsuarios = new UsuarioRepositorio().GetAllUsers(); return listaUsuarios; } } } b. LoginController.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using ProsaMail.Entidades; using ProsaMail.ContextoDAL.Repositorios; namespace ProsaMail.Controller { class LoginController { public Usuario verificaDadosLogin(Usuario usu, bool cadastrar = false) { Usuario usuEncontrado = new UsuarioRepositorio().FindLogin(usu); //NÃO ENCONTROU O USUARIO E NÃO É PARA CADASTRAR if (usuEncontrado.UsuarioID <= 0 && !cadastrar) { Questions.usuarioNaoEncontrado(); usu.UsuarioID = 0; return usu; } 27 //NÃO ENCONTROU USUARIO MAS É PARA CADASTRAR else if (usuEncontrado.UsuarioID <= 0 && cadastrar) { usu = new UsuarioRepositorio().AdicionarUsuario(usu); if (usu.UsuarioID > 0) { Questions.usuarioCadastrado(); } } else if (usuEncontrado.UsuarioID > 0 && (usu.User_senha != usuEncontrado.User_senha)) { Questions.senhaIncorreta(); usu.UsuarioID = 0; return usu; } else { usu = usuEncontrado; } return usu; } } } 8. Forms(Telas) a. CadastroServidor.cs using ProsaMail.Aparencia; using ProsaMail.Configs; using ProsaMail.Controller; using ProsaMail.Entidades; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using ChatServidorProsa; namespace ProsaMail.Forms { public partial class CadastroServidor : Form { 28 private static CadastroServidor instance; private delegate voidAtualizaStatusCallback(string strMensagem); public IPAddress[] ips = null; public IPAddress ipGrupo = null; public String nomeGrupo; Configuracoes config = new Configuracoes(); LoginController control = new LoginController(); public static CadastroServidor getInstance { get { if (instance == null) { instance = new CadastroServidor(); } return instance; } } public CadastroServidor() { config.Tema = "Dark"; Themes theme = new Themes(); if (config.Tema == "Dark") { this.BackColor = theme.BackGroundDark; this.ForeColor = theme.LblColorDark; } InitializeComponent(); string nome = Dns.GetHostName(); ips = Dns.GetHostAddresses(nome).Where(i => i.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).ToArray(); if (ips.Count() > 1) { ipGrupo = ips[1]; } else { ipGrupo = ips.First(); } txtIpGrupo.Text = ipGrupo.ToString(); //IPS AWS Servidor - 54.233.110.241 e 54.94.142.53 //string nomeAws = "db-faculdade.cuktluvpqokp.sa-east- 1.rds.amazonaws.com"; 29 } private void btnSalvar_Click(object sender, EventArgs e) { if (txtIpGrupo.Text == "") { Questions.informarNomeGrupo(); txtNomeGrupo.Focus(); } else { nomeGrupo = txtNomeGrupo.Text; this.DialogResult = DialogResult.OK; this.Close(); } } private void btnSair_Click(object sender, EventArgs e) { ipGrupo = null; this.Close(); } private void CadastroServidor_KeyDown(object sender, KeyEventArgs e) { if (e.KeyData == Keys.Escape) { ipGrupo = null; } if (e.KeyData == Keys.Enter) { btnSalvar.PerformClick(); } Funcoes.padronizaTeclas(e, this); } } } b. CadastroUsu.cs using ProsaMail.Aparencia; using ProsaMail.Configs; using ProsaMail.Controller; using ProsaMail.Entidades; using System; using System.Collections.Generic; using System.ComponentModel; 30 using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace ProsaMail.Forms { public partial class CadastroUsu : Form { public int idUsuarioCadastrado = 0; Configuracoes config = new Configuracoes(); LoginController control = new LoginController(); public CadastroUsu() { config.Tema = "Dark"; Themes theme = new Themes(); if (config.Tema == "Dark") { this.BackColor = theme.BackGroundDark; this.ForeColor = theme.LblColorDark; } InitializeComponent(); } private void button4_Click(object sender, EventArgs e) { this.Close(); } private void limpaCampos() { txtUsuario.Text = ""; txtSenha.Text = ""; txtNome.Text = ""; txtConfirmaSenha.Text = ""; } private void btnSalvar_Click(object sender, EventArgs e) { if (txtUsuario.Text == "" || txtSenha.Text == "") { Questions.usuSenNaoInformados(); txtSenha.Focus(); } else if (txtSenha.Text != txtConfirmaSenha.Text) 31 { Questions.senhaNaoConfere(); txtConfirmaSenha.Focus(); } else { Usuario usuario = new Usuario(); usuario.User_login = txtUsuario.Text; usuario.User_senha = txtSenha.Text; usuario.User_name = txtNome.Text; Usuario usuEncontrado = control.verificaDadosLogin(usuario, true); if (usuEncontrado.UsuarioID <= 0) { idUsuarioCadastrado = usuario.UsuarioID; this.DialogResult = DialogResult.OK; this.Close(); } else { Questions.usuarioJaExiste(); limpaCampos(); } } } private void btnSair_Click(object sender, EventArgs e) { this.Close(); } } } c. ConfigEmail.cs using ProsaMail.Aparencia; using ProsaMail.Configs; using ProsaMail.Controller; using ProsaMail.Entidades; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using ChatServidorProsa; 32 namespace ProsaMail.Forms { public partial class ConfigEmail : Form { private static ConfigEmail instance; Configuracoes config = new Configuracoes(); public string userEmail = "recent:seuemail@gmail.com"; // Usuário do servidor POP3. Por exemplo, seuemail@gmail.com. public string password = "SUA_SENHA"; // Senha do servidor POP3. public static ConfigEmail getInstance { get { if (instance == null) { instance = new ConfigEmail(); } return instance; } } public ConfigEmail() { config.Tema = "Dark"; Themes theme = new Themes(); if (config.Tema == "Dark") { this.BackColor = theme.BackGroundDark; this.ForeColor = theme.LblColorDark; } InitializeComponent(); } private void btnSalvar_Click(object sender, EventArgs e) { if (txtEmail.Text == "") { Questions.usuSenNaoInformados(); txtEmail.Focus(); } else if (!txtEmail.Text.Contains("gmail.com")) { Questions.emailNaoGmail(); txtEmail.Focus(); } 33 else if (txtSenha.Text == "") { Questions.usuSenNaoInformados(); txtEmail.Focus(); } else { userEmail = txtEmail.Text; password = txtSenha.Text; this.DialogResult = DialogResult.OK; this.Close(); } } private void btnSair_Click(object sender, EventArgs e) { userEmail = ""; password = ""; this.Close(); } private void CadastroServidor_KeyDown(object sender, KeyEventArgs e) { if (e.KeyData == Keys.Escape) { userEmail = ""; password = ""; } if (e.KeyData == Keys.Enter) { btnSalvar.PerformClick(); } Funcoes.padronizaTeclas(e, this); } private void ConfigEmail_Load(object sender, EventArgs e) { txtEmail.Focus(); } } } d. Contatos.cs using ProsaMail.Aparencia;using ProsaMail.Configs; using ProsaMail.Controller; 34 using ProsaMail.Entidades; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace ProsaMail.Forms { public partial class Contatos : Form { Configuracoes config = new Configuracoes(); ContatosController control = new ContatosController(); List<Usuario> listaUsuarios = new List<Usuario>(); public Usuario usuarioEscolhido = new Usuario(); List<Button> listaBtn = new List<Button>(); public Contatos() { config.Tema = "Dark"; Themes theme = new Themes(); if (config.Tema == "Dark") { this.BackColor = theme.BackGroundDark; this.ForeColor = theme.LblColorDark; } InitializeComponent(); } private void Contatos_KeyDown(object sender, KeyEventArgs e) { Funcoes.padronizaTeclas(e, this); } private void Contatos_Load(object sender, EventArgs e) { listaUsuarios = control.listaTodos_Usuarios(); if (listaUsuarios.Count() > 0) { for (int i = 0; i < listaUsuarios.Count(); i++) { 35 Button btn = new Button(); btn = criaNovoBotao(btn, i); btn.Text = listaUsuarios[i].User_name + "(" + listaUsuarios[i].User_login + ")"; btn.Visible = true; if (i > 0) { btn.Top = listaBtn[i - 1].Bottom + 2; } else if (i == 0) { btn.Location = new Point(0, 0); } listaBtn.Add(btn); this.Controls.Add(btn); //this.panel1.Controls.Add(btn); } } } private Button criaNovoBotao(Button btn, int i) { btn.BackColor = btnContato.BackColor; btn.Dock = btnContato.Dock; btn.FlatAppearance.BorderColor = btnContato.FlatAppearance.BorderColor; btn.FlatAppearance.MouseDownBackColor = btnContato.FlatAppearance.MouseDownBackColor; btn.FlatAppearance.MouseOverBackColor = btnContato.FlatAppearance.MouseOverBackColor; btn.FlatStyle = btnContato.FlatStyle; btn.Font = btnContato.Font; btn.ForeColor = btnContato.ForeColor; btn.ImageAlign = btnContato.ImageAlign; btn.Name = "btn" + i.ToString(); btn.Padding = btnContato.Padding; btn.Size = btnContato.Size; btn.TabIndex = i; btn.TextAlign = btnContato.TextAlign; btn.TextImageRelation = btnContato.TextImageRelation; btn.UseVisualStyleBackColor = btnContato.UseVisualStyleBackColor; btn.Visible = true; btn.Click += new EventHandler(this.btnContato_Click); return btn; } private void btnContato_Click(object sender, EventArgs e) 36 { foreach (Usuario usu in listaUsuarios) { var usuClick = sender.ToString().Replace(")", "").Split('('); if (usu.User_login == usuClick[1]) { usuarioEscolhido = usu; break; } } this.Close(); } } } e. Login.cs using ProsaMail.Aparencia; using ProsaMail.Configs; using ProsaMail.Controller; using ProsaMail.Entidades; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace ProsaMail.Forms { public partial class Login : Form { Configuracoes config = new Configuracoes(); LoginController control = new LoginController(); public Usuario usuario = new Usuario(); MiniSplash splash; private bool done = false; public Login() { config.Tema = "Dark"; Themes theme = new Themes(); if (config.Tema == "Dark") { 37 this.BackColor = theme.BackGroundDark; this.ForeColor = theme.LblColorDark; } InitializeComponent(); } private void button4_Click(object sender, EventArgs e) { this.Close(); } private void btnCadastrar_Click(object sender, EventArgs e) { CadastroUsu form = new CadastroUsu(); form.Show(); } private void btnSair_Click(object sender, EventArgs e) { this.Close(); } private void btnEntrar_Click(object sender, EventArgs e) { if (txtUsuario.Text == "" || txtSenha.Text == "") { Questions.usuSenNaoInformados(); habilitarCampos(true); } else { if (!bw.IsBusy) { habilitarCampos(false); splash = new MiniSplash(); splash.Location = new Point(this.Location.X + 3, this.Location.Y + 3); bw.RunWorkerAsync("Busca"); } } } private void executaEntrada() { if (txtUsuario.InvokeRequired) { BeginInvoke(new Action(() => this.executaEntrada())); return; } else 38 { usuario.User_login = txtUsuario.Text; usuario.User_senha = txtSenha.Text; usuario = control.verificaDadosLogin(usuario); if (usuario.UsuarioID > 0) { splash.fecharSplash(); bw.Dispose(); } //while (!done) //{ // Application.DoEvents(); //} } } private void habilitarCampos(bool flag) { btnCadastrar.Enabled = flag; btnEntrar.Enabled = flag; btnSair.Enabled = flag; label2.Enabled = flag; label3.Enabled = flag; txtSenha.Enabled = flag; txtUsuario.Enabled = flag; imgProsaMail.Enabled = flag; } private void Login_KeyDown(object sender, KeyEventArgs e) { if (e.KeyData == Keys.Enter) { btnEntrar.PerformClick(); } Funcoes.padronizaTeclas(e, this); } private void bw_DoWork(object sender, DoWorkEventArgs e) { String tipo = Convert.ToString(e.Argument); switch (tipo) { case "Busca": 39 Thread thEntrada = new Thread(new ThreadStart(this.executaEntrada)); thEntrada.Start(); splash.ShowDialog(); break; } } private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { bw = new BackgroundWorker(); bw.DoWork += new DoWorkEventHandler(bw_DoWork); bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted); this.DialogResult = DialogResult.OK;done = true; habilitarCampos(true); } } } f. MiniSplash.cs using ProsaMail.Aparencia; using ProsaMail.Configs; using ProsaMail.Controller; using ProsaMail.Entidades; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace ProsaMail.Forms { public partial class MiniSplash : Form { private delegate void ProgressDelegate(int progress); private ProgressDelegate del; public MiniSplash() { InitializeComponent(); this.circularProgressBar1.Maximum = 100; del = this.UpdateProgressInternal; 40 } private void UpdateProgressInternal(int progress) { if (this.Handle == null) { return; } this.circularProgressBar1.Value = progress; } public void UpdateProgress(int progress) { this.Invoke(del, progress); } public void fecharSplash() { if (this.InvokeRequired) { this.BeginInvoke((MethodInvoker)delegate { fecharSplash(); }); } else { this.Close(); } } } } g. NovoEmail.cs using ProsaMail.Aparencia; using ProsaMail.Configs; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.IO; 41 using System.Threading; using ProsaMail.Entidades; using NLog.Fluent; using ChatServidorProsa; using ProsaMail.Model; using System.Text.RegularExpressions; using Microsoft.Win32; using System.Net.Mail; using System.Net.Mime; namespace ProsaMail.Forms { public partial class NovoEmail : Form { private static NovoEmail instance; Configuracoes config = new Configuracoes(); private String emailConta = ""; private String senha = ""; public EnvioEmailModel envio = new EnvioEmailModel(); public static NovoEmail getInstance(String emailConta, String senha) { if (instance == null) { instance = new NovoEmail(emailConta, senha); } return instance; } public NovoEmail() { try { config.Tema = "Dark"; Themes theme = new Themes(); if (config.Tema == "Dark") { this.BackColor = theme.BackGroundDark; this.ForeColor = theme.LblColorDark; } InitializeComponent(); } catch (Exception erro) { } 42 } public NovoEmail(String emailConta, String senha) : this() { this.emailConta = emailConta; lblEmailConta.Text = emailConta; this.senha = senha; } private void Principal_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Escape) { } } private void btnEnviar_Click(object sender, EventArgs e) { envioEmail(); this.DialogResult = DialogResult.OK; } private async void envioEmail() { try { using (SmtpClient smtp = new SmtpClient()) { smtp.Host = "smtp.gmail.com"; smtp.Port = 587; smtp.EnableSsl = true; smtp.UseDefaultCredentials = false; smtp.Credentials = new NetworkCredential(emailConta, senha); using (MailMessage mail = new MailMessage()) { mail.From = new MailAddress(emailConta); if (!string.IsNullOrWhiteSpace(txtPara.Text)) { mail.To.Add(new MailAddress(txtPara.Text)); } else { DarkUI.Forms.DarkMessageBox.ShowWarning("Campo 'para' é obrigatório.", "Erro", DarkUI.Forms.DarkDialogButton.Ok); envio = null; } if (!string.IsNullOrWhiteSpace(txtCC.Text)) 43 mail.CC.Add(new MailAddress(txtCC.Text)); mail.Subject = txtAssunto.Text; mail.Body = rtxtBody.Text; envio.Smtp = smtp; envio.Email = mail; await smtp.SendMailAsync(mail); } } } catch (Exception erro) { throw erro; } } } } h. Principal.cs using ProsaMail.Aparencia; using ProsaMail.Configs; using System; using System.Collections.Generic; using System.Data; using System.Drawing; using System.Linq; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using System.IO; using System.Threading; using ProsaMail.Entidades; using NLog.Fluent; using ChatServidorProsa; using ProsaMail.Model; using Microsoft.Win32; using ProsaMail.ContextoDAL.Repositorios; namespace ProsaMail.Forms { public partial class Principal : Form { Configuracoes config = new Configuracoes(); // Trata o nome do usuário private string NomeUsuario = "Desconhecido"; private StreamWriter stwEnviador; 44 private StreamReader strReceptor; private TcpClient tcpServidor; // Necessário para atualizar o formulário com mensagens da outra thread private delegate void AtualizaLogCallBack(string strMensagem); // Necessário para definir o formulário para o estado "disconnected" de outra thread private delegate void FechaConexaoCallBack(string strMotivo); private Thread mensagemThread; private bool Conectado; private delegate void AtualizaStatusCallback(string strMensagem); private List<string> logString = new List<string>(); public Usuario usuarioLogado = new Usuario(); List<Label> listaTxt = new List<Label>(); string direcaoMsg = ""; IPAddress ipGrupoServ; ChatServidorProsa.ChatServidorProsa mainServidor; List<Bitmap> listaImagens = new List<Bitmap>(); bool atualizando = false; //CONFIGURAÇÕES EMAIL private List<EmailModel> _emailsCxEntrada = new List<EmailModel>(); private List<EmailModel> _emailsEnviados = new List<EmailModel>(); private List<string[]> emailsLista = new List<string[]>(); private string _hostname = "pop.gmail.com"; // Host do seu servidor POP3. Por exemplo, pop.gmail.com para o servidor do Gmail. private int _port = 995; // Porta utilizada pelo host. Por exemplo, 995 para o servidor do Gmail. private bool _useSsl = true; // Indicação se o servidor POP3 utiliza SSL para autenticação. Por exemplo, o servidor do Gmail utiliza SSL, então, "true". private string _username; //"recent:seuemail@gmail.com"; // Usuário do servidor POP3. Por exemplo, seuemail@gmail.com. private string _password = "SUA_SENHA"; // Senha do servidor POP3. public Principal(Usuario usuario) {try { this.usuarioLogado = usuario; NomeUsuario = usuarioLogado.User_login; config.Tema = "Dark"; Themes theme = new Themes(); if (config.Tema == "Dark") { this.BackColor = theme.BackGroundDark; this.ForeColor = theme.LblColorDark; } 45 // Na saida da aplicação : desconectar Application.ApplicationExit += new EventHandler(OnApplicationExit); InitializeComponent(); VerifyVersion(WebBrowserRecebidos); Email emailUsu = new EmailRepositorio().FindConfigEmail(usuarioLogado); if (emailUsu.Email_name == "" || emailUsu.Email_name == null) { //inicia configuração de email ConfigEmail formConfigEmail = ConfigEmail.getInstance; formConfigEmail.ShowDialog(); if (formConfigEmail.userEmail != "" && formConfigEmail.userEmail != "" && formConfigEmail.password != "") { _username = "recent:" + formConfigEmail.userEmail; lblEmailConta.Text = formConfigEmail.userEmail; _password = formConfigEmail.password; emailUsu.Host_Name = _username; emailUsu.Email_name = formConfigEmail.userEmail; emailUsu.Password = _password; emailUsu.Email_date = DateTime.Now; emailUsu = new EmailRepositorio().AdicionarEmail(emailUsu, usuarioLogado); if (emailUsu.EmailID > 0) { Questions.configEmailCadastrada(); } } } else { _username = emailUsu.Host_Name; lblEmailConta.Text = emailUsu.Email_name; _password = emailUsu.Password; } } catch (Exception erro) { } } public void redimencionaForm() { 46 double aTela = Convert.ToDouble(Funcoes.FromHeight); double lTela = Convert.ToDouble(Funcoes.FromWidth); double aPadrao = Funcoes.aPadrao; double lPadrao = Funcoes.lPadrao; Funcoes.redimencionaForm(this); if (aTela < aPadrao || lTela < lPadrao) { Funcoes.calculaProporcao(); double proporcaoLargura = Funcoes.proporcaoLargura; double proporcaoAltura = Funcoes.proporcaoAltura; int telaDois = Convert.ToInt32(this.Height / 2); pnlFundo.Width = this.Width - (panel1.Width + txtMensagens.Width + 45); } } public void VerifyVersion(WebBrowser webbrowser) { string appName = ""; try { appName = System.Diagnostics.Process.GetCurrentProcess().ProcessName + ".exe"; RegistryKey fbeKey = null; ////For 64 bit Machine fbeKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"SOFTWARE\\Wow6432N ode\\Microsoft\\Internet Explorer\\MAIN\\FeatureControl\\FEATURE_BROWSER_EMULATION", true); if (fbeKey == null) fbeKey = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\\Wow6432Node\\Microsoft\\ Internet Explorer\\MAIN\\FeatureControl\\FEATURE_BROWSER_EMULATION"); using (fbeKey) { fbeKey.SetValue(appName, 11001, RegistryValueKind.DWord); } //For 32 bit Machine fbeKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(@"SOFTWARE\\Microsoft\\I nternet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", true); 47 if (fbeKey == null) fbeKey = Registry.CurrentUser.CreateSubKey(@"SOFTWARE\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION"); using (fbeKey) { fbeKey.SetValue(appName, 11001, RegistryValueKind.DWord); } } catch (Exception ex) { MessageBox.Show(appName + "\n" + ex.ToString(), "Unexpected error setting browser mode!"); } } public void clickOcultaTxt(TextBox textBox) { if (textBox.Text == "Buscar" || textBox.Text == "Digite uma mensagem") { textBox.Text = ""; } } private void txtMsgTemp_KeyDown(object sender, KeyEventArgs e) { clickOcultaTxt(txtMsgTemp); if (txtMsgTemp.Text != "" && txtMsgTemp.Text != "Digite uma mensagem") { btnEnviar.Enabled = true; txtMsgTemp.Width = 318; } else { btnEnviar.Enabled = false; txtMsgTemp.Width = 369; } } private void txtMsgTemp_MouseClick(object sender, MouseEventArgs e) { clickOcultaTxt(txtMsgTemp); } 48 private void txtMsgTemp_Leave(object sender, EventArgs e) { if (txtMsgTemp.Text == "") { txtMsgTemp.Text = "Digite uma mensagem"; } } private void txtMsgTemp_TextChanged(object sender, EventArgs e) { if (txtMsgTemp.Text != "" && txtMsgTemp.Text != "Digite uma mensagem") { btnEnviar.Visible = true; txtMsgTemp.Width = 318; } else { btnEnviar.Visible = false; txtMsgTemp.Width = 369; } } private void btnNovaProsa_Click(object sender, EventArgs e) { try { if (Conectado) { if (Questions.encerrarServidorAnterior(btnNomeGrupo.Text) == DialogResult.Yes) { FechaConexaoCliente("O grupo foi encerrado!"); OnApplicationExit(sender, e); txtMensagens.Lines = null; } else { return; } } CadastroServidor form = CadastroServidor.getInstance; form.ShowDialog(); if (form.ipGrupo != null) { ipGrupoServ = form.ipGrupo; lblApresentaChat.Visible = false; 49 btnNomeGrupo.Visible = true; btnNomeGrupo.Text = form.nomeGrupo; if (Conectado == false) { iniciaAtendimentoCliente(); InicializaConexaoCliente(); txtMsgTemp.Focus(); } else // Se esta conectado entao desconecta { FechaConexaoCliente("Desconectado a pedido do usuário."); } } form.Close(); } catch (Exception erro) { MessageBox.Show(erro.Message); throw; } } private void Principal_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Escape) { } }private void InicializaConexaoCliente() { tcpServidor = new TcpClient(); tcpServidor.Connect(ipGrupoServ, 2502); Conectado = true; // Envia o nome do usuário ao servidor stwEnviador = new StreamWriter(tcpServidor.GetStream()); stwEnviador.WriteLine(NomeUsuario); stwEnviador.Flush(); //Inicia a thread para receber mensagens e nova comunicação mensagemThread = new Thread(new ThreadStart(RecebeMensagens)); mensagemThread.Start(); } private void RecebeMensagens() 50 { try { // recebe a resposta do servidor strReceptor = new StreamReader(tcpServidor.GetStream()); string ConResposta = strReceptor.ReadLine(); // Se o primeiro caracater da resposta é 1 a conexão foi feita com sucesso if (ConResposta[0] == '1') { direcaoMsg = "inBox"; // Atualiza o formulário para informar que esta conectado this.Invoke(new AtualizaLogCallBack(this.AtualizaLog), new object[] { "Conectado com sucesso!" }); } else // Se o primeiro caractere não for 1 a conexão falhou { string Motivo = "Não Conectado: "; // Extrai o motivo da mensagem resposta. O motivo começa no 3o caractere Motivo += ConResposta.Substring(2, ConResposta.Length - 2); // Atualiza o formulário como o motivo da falha na conexão this.Invoke(new FechaConexaoCallBack(this.FechaConexaoCliente), new object[] { Motivo }); // Sai do método return; } // Enquanto estiver conectado le as linhas que estão chegando do servidor while (Conectado) { direcaoMsg = "inBox"; // exibe mensagems no Textbox this.Invoke(new AtualizaLogCallBack(this.AtualizaLog), new object[] { strReceptor.ReadLine() }); } } catch (Exception erro) { Log.Error("RecebeMeensagem" + erro); //this.Dispose(); } } private void AtualizaLog(string strMensagem) { // Anexa texto ao final de cada linha txtMensagens.AppendText(strMensagem + "\r\n"); 51 txtMsgTemp.Lines = null; } // Envia a mensagem para o servidor private void EnviaMensagem() { if (txtMsgTemp.Lines.Length >= 1) { //escreve a mensagem da caixa de texto stwEnviador.WriteLine(txtMsgTemp.Text); stwEnviador.Flush(); direcaoMsg = "outBox"; } } private void FechaConexaoCliente(string Motivo) { try { // Mostra o motivo porque a conexão encerrou string motivo = Motivo + "\r\n"; // Fecha os objetos strReceptor.Close(); tcpServidor.Close(); stwEnviador.Close(); } catch (Exception erro) { throw erro; } } // O tratador de evento para a saida da aplicação public void OnApplicationExit(object sender, EventArgs e) { if (Conectado == true) { // Fecha as conexões, streams, etc... Conectado = false; stwEnviador.Close(); strReceptor.Close(); tcpServidor.Close(); } } private void btnNomeGrupo_VisibleChanged(object sender, EventArgs e) { if (btnNomeGrupo.Visible) { //txtMensagens.Location = new Point(621, 154); lblApresentaChat.Visible = false; 52 } } private void btnEnviar_Click_1(object sender, EventArgs e) { EnviaMensagem(); } private void txtMsgTemp_KeyPress(object sender, KeyPressEventArgs e) { // Se pressionou a tecla Enter if (e.KeyChar == (char)13) { EnviaMensagem(); } } public void mainServidor_StatusChanged(object sender, StatusChangedEventArgs e) { // Chama o método que atualiza o formulário this.Invoke(new AtualizaStatusCallback(this.AtualizaLog), new object[] { e.EventMessage }); } public void iniciaAtendimentoCliente() { try { // Analisa o endereço IP do servidor informado no textbox IPAddress enderecoIP = ipGrupoServ; // Cria uma nova instância do objeto ChatServidor mainServidor = new ChatServidorProsa.ChatServidorProsa(enderecoIP); // Vincula o tratamento de evento StatusChanged a mainServer_StatusChanged ChatServidorProsa.ChatServidorProsa.StatusChanged += new StatusChangedEventHandler(mainServidor_StatusChanged); // Inicia o atendimento das conexões mainServidor.IniciaAtendimento(); // Mostra que nos iniciamos o atendimento para conexões //txtLog.AppendText("Monitorando as conexões...\r\n"); } catch (Exception ex) { Log.Error("Erro de conexão : " + ex.Message); 53 } } private void btnSair_Click(object sender, EventArgs e) { this.Close(); } private void btnAtualiza_Click(object sender, EventArgs e) { atualizando = true; try { if (lblEmailConta.Text != "") { Cursor = Cursors.WaitCursor; using (var client = new OpenPop.Pop3.Pop3Client()) { client.Connect(_hostname, _port, _useSsl); client.Authenticate(_username, _password); _emailsCxEntrada.Clear(); _emailsEnviados.Clear(); int messageCount = client.GetMessageCount(); for (int i = messageCount; i > 0; i--) { var popEmail = client.GetMessage(i); var popText = popEmail.FindFirstPlainTextVersion(); var popHTML = popEmail.FindFirstHtmlVersion(); var anexos = popEmail.FindAllAttachments(); string mailText = string.Empty; string mailHtml = string.Empty; if (popText != null) { mailText = popText.GetBodyAsText(); } if (popHTML != null) { mailHtml = popHTML.GetBodyAsText(); mailHtml = mailHtml.Replace("<body>", "<body style='background-color:rgb(30, 30, 30); color:white'>"); } 54 EmailModel objEmail = new EmailModel(); objEmail.ResumoEmail = popEmail.Headers.From.Address + "\n" + popEmail.Headers.Subject + "\n" + mailText; objEmail.Id = popEmail.Headers.MessageId;objEmail.Assunto = popEmail.Headers.Subject; objEmail.De = popEmail.Headers.From.Address; objEmail.Para = string.Join("; ", popEmail.Headers.To.Select(to => to.Address)); objEmail.Data = TimeZoneInfo.ConvertTime(popEmail.Headers.DateSent, TimeZoneInfo.FindSystemTimeZoneById("E. South America Standard Time")); objEmail.ConteudoTexto = mailText; objEmail.ConteudoHtml = !string.IsNullOrWhiteSpace(mailHtml) ? mailHtml : mailText; if (anexos.Count > 0) { foreach (OpenPop.Mime.MessagePart item in anexos) { if (item.ContentType.MediaType == "image/jpeg") { objEmail.ConteudoHtml += objEmail.AlternateView; objEmail.Imagens.Add(byteArrayToImage(item.Body)); listaImagens.Add(byteArrayToImage(item.Body)); } } objEmail.Anexos = anexos; } if (objEmail.De == lblEmailConta.Text) { _emailsEnviados.Add(objEmail); } else { _emailsCxEntrada.Add(objEmail); } } AtualizarDataBindings(); } } else { Email emailUsu = new Email(); ConfigEmail formConfigEmail = ConfigEmail.getInstance; formConfigEmail.ShowDialog(); 55 if (formConfigEmail.userEmail != "" && formConfigEmail.userEmail != "" && formConfigEmail.password != "") { _username = "recent:" + formConfigEmail.userEmail; lblEmailConta.Text = formConfigEmail.userEmail; _password = formConfigEmail.password; emailUsu.Host_Name = _username; emailUsu.Email_name = formConfigEmail.userEmail; emailUsu.Password = _password; emailUsu.Email_date = DateTime.Now; emailUsu = new EmailRepositorio().AdicionarEmail(emailUsu, usuarioLogado); if (emailUsu.EmailID > 0) { Questions.configEmailCadastrada(); } } } } catch (Exception ex) { Log.Error("Erro de email : " + ex.Message); Questions.erroConfigEmail(); Email emailUsu = new Email(); ConfigEmail formConfigEmail = ConfigEmail.getInstance; formConfigEmail.ShowDialog(); if (formConfigEmail.userEmail != "" && formConfigEmail.userEmail != "" && formConfigEmail.password != "") { _username = "recent:" + formConfigEmail.userEmail; lblEmailConta.Text = formConfigEmail.userEmail; _password = formConfigEmail.password; emailUsu.Host_Name = _username; emailUsu.Email_name = formConfigEmail.userEmail; emailUsu.Password = _password; emailUsu.Email_date = DateTime.Now; emailUsu = new EmailRepositorio().AdicionarEmail(emailUsu, usuarioLogado); if (emailUsu.EmailID > 0) { Questions.configEmailCadastrada(); 56 } } } finally { Cursor = Cursors.Default; atualizando = false; } } public Bitmap byteArrayToImage(byte[] bytesArr) { using (MemoryStream memstr = new MemoryStream(bytesArr)) { Bitmap img = (Bitmap)Image.FromStream(memstr); return img; } } private void AtualizarDataBindings() { try { // Limpando os bindings. txtDe.DataBindings.Clear(); txtPara.DataBindings.Clear(); txtAssunto.DataBindings.Clear(); dtpDataEmail.DataBindings.Clear(); WebBrowserEnviados.DataBindings.Clear(); WebBrowserRecebidos.DataBindings.Clear(); lstCaixaEntrada.DataSource = null; lstEnviados.DataSource = null; RecebidosBindingSource.DataSource = null; EnviadosBindingSource.DataSource = null; // Re-configurando os bindings. //ENVIADOS EnviadosBindingSource.DataSource = _emailsEnviados; lstEnviados.DataSource = EnviadosBindingSource; lstEnviados.DisplayMember = "Assunto"; //RECEBIDOS RecebidosBindingSource.DataSource = _emailsCxEntrada; lstCaixaEntrada.DataSource = RecebidosBindingSource; lstCaixaEntrada.DisplayMember = "Assunto"; txtDe.DataBindings.Add(new Binding("Text", RecebidosBindingSource, "De")); 57 txtPara.DataBindings.Add(new Binding("Text", RecebidosBindingSource, "Para")); txtAssunto.DataBindings.Add(new Binding("Text", RecebidosBindingSource, "Assunto")); dtpDataEmail.DataBindings.Add(new Binding("Text", RecebidosBindingSource, "Data")); WebBrowserEnviados.DataBindings.Add(new Binding("DocumentText", EnviadosBindingSource, "ConteudoHtml")); WebBrowserRecebidos.DataBindings.Add(new Binding("DocumentText", RecebidosBindingSource, "ConteudoHtml")); exibeCamposEmail(true); } catch (Exception ex) { Log.Error("Erro de binding : " + ex.Message); } } private void AtualizarDataBindingsTextBox(bool enviados = false) { try { // Limpando os bindings. txtDe.DataBindings.Clear(); txtPara.DataBindings.Clear(); txtAssunto.DataBindings.Clear(); dtpDataEmail.DataBindings.Clear(); if (enviados) { txtDe.DataBindings.Add(new Binding("Text", EnviadosBindingSource, "De")); txtPara.DataBindings.Add(new Binding("Text", EnviadosBindingSource, "Para")); txtAssunto.DataBindings.Add(new Binding("Text", EnviadosBindingSource, "Assunto")); dtpDataEmail.DataBindings.Add(new Binding("Text", EnviadosBindingSource, "Data")); } else { txtDe.DataBindings.Add(new Binding("Text", RecebidosBindingSource, "De")); txtPara.DataBindings.Add(new Binding("Text", RecebidosBindingSource, "Para")); txtAssunto.DataBindings.Add(new Binding("Text", RecebidosBindingSource, "Assunto")); dtpDataEmail.DataBindings.Add(new Binding("Text", RecebidosBindingSource, "Data")); 58 } exibeCamposEmail(true); } catch (Exception ex)