예제 #1
0
        /// <summary>
        ///Unico ponto para enviar mensagens assincronas para a lista de mensagens a enviar
        ///Desdobra mensagens que estejam indicadas como broadcast
        /// </summary>
        /// <param name="mensagem">Mensagem a meter na lista para enviar</param>
        public static void MeteMensagemParaEnviar(Mensagem mensagem)
        {
            ArrayList servidoresVivos = ServerMain.ServidoresVivos;
             //E a mensagem for para enviar em broadcast
             if (mensagem._idDestinatarioMensagem.Equals(Mensagem.IPBROADCAST))
             {
            //preciso de multiplicar mensagem para enviar pa todos os servidores
            Configuration.Debug(Configuration.DEBUG_VOU_REALIZAR_BROADCAST, Configuration.PRI_MIN);
            foreach (Servidor servidor in servidoresVivos)
            {
               Mensagem clone = mensagem.DuplicaMsg();
               clone._idDestinatarioMensagem = servidor.Identificacao;
               lock (_outbox)
               {
                  _outbox.Add(clone);
               }
            }
             }

               //Se nao for uma mensagem em broadcast
             else
             {
            lock (_outbox)
            {
               _outbox.Add(mensagem);
            }
             }
        }
예제 #2
0
        /// <summary>
        /// Fila de mensagem de entrada, e por aqui que devem receber as mensagem para o servidor
        /// </summary>
        /// <param name="tipoMsg"> define o tipo de mensagem k se pretende receber
        /// </param>
        /// <param name="obj"> varia conforme o tipo de mensagem
        ///     "criaJogo" - {nomeMapa, nomeConfig}
        /// </param>
        /// <returns> varia conforme a mensagem
        ///     "criaJogo" - {idJogo}
        /// </returns>
        public void MessageQueue(Mensagem mensagem)
        {
            //Se for uma mensagem vinda de um cliente
             if (mensagem.TipoMensagemCliente() == true)
             {
            try
            {
               DoLockGeral();
               #region Mensagens vindas do cliente
               MensagemCliente msgArranjada = (MensagemCliente)mensagem;
               //Se for uma tentativa de abrir tesouro
               if (mensagem.TipoIgual(Mensagem.ABRETESOURO))
               {
                  TrataAberturaTesouro(msgArranjada.Nick, msgArranjada.Sala, msgArranjada.IdJogo);
                  return;
               }

               //se for um movimento
               if (mensagem.TipoIgual(Mensagem.MOVIMENTO))
               {
                  MensagemCliente mensagemRetorno = ServicosEntrada.MovimentoJogador(msgArranjada.Nick, msgArranjada.Sala, msgArranjada.IdJogo);
                  MeteMensagemParaEnviar(mensagemRetorno);
                  return;
               }
               #endregion
            }
            finally
            {
               DoUnlockGeral();
            }
             }

             //Se for uma mensagem vinda de um servidor
             if (mensagem.TipoMensagemServidor() == true)
             {
            #region Mensagens vindas de um servidor
            Configuration.Debug("Recebi uma mensagem do servidor " + mensagem._idOriginadorMensagem, Configuration.PRI_MIN);

            //Vamos ver se esse servidor nao devia estar morto
            if (Servidor.ServidorEstaVivo(mensagem._idOriginadorMensagem, ServerMain.TodosServidores) == false)
            {
               Configuration.Debug("Recebi uma mensagem de um servidor ja declarado como morto", Configuration.PRI_MAX);
               MensagemServidor msg = MensagemServidor.MensagemAvisoFosteDeclaradoMorto(ServerMain._minhaIdentificacao, mensagem._idOriginadorMensagem);
               MeteMensagemParaEnviar(msg);
               return;
            }

            MensagemServidor msgArranjada = (MensagemServidor)mensagem;
            string idJogo = msgArranjada.IdJogo;
            string idCliente = msgArranjada.IdCliente;
            int pontuacaoAntiga = msgArranjada.PontuacaoAntiga;
            int pontuacaoNova = msgArranjada.PontuacaoNova;
            bool jogoTerminou = msgArranjada.JogoTerminou;

            //Se for uma mensagem de retorno
            if (msgArranjada.EMsgDeRetorno() == true)
            {
               string guid = msgArranjada.guidUnico;
               //Vou ver se é retorno para mim
               lock (_lstRespostasMensagensPendentes)
               {
                  if (MensagemServidor.ListaContemMensagem(guid, _lstRespostasMensagensPendentes) == true)
                  {
                     Configuration.Debug("Recebi o retorno de uma msg que enviei.", Configuration.PRI_MIN);
                     MensagemServidor.RemoveMensagemPorGuid(guid, _lstRespostasMensagensPendentes);
                  }
               }
            }

            if (mensagem.TipoIgual(Mensagem.UPDATEESTADOGLOBAL))
            {
               Configuration.Debug("Vou realizar um update do meu estado ", Configuration.PRI_MED);
               RoomDesc novaSala = msgArranjada.NovaSala;
               string resultadoAccaoCliente = msgArranjada.ResultadoAccaoCliente;
               ServicosEntrada.RealizaUpdateDoEstado(idJogo, novaSala, idCliente, pontuacaoAntiga, pontuacaoNova, jogoTerminou, resultadoAccaoCliente);
               RelogioVectorial.IncrementaServidor(mensagem._idOriginadorMensagem, ServerMain._lstRelogiosVectoriais);
               return;
            }

            if (mensagem.TipoIgual(Mensagem.TENTATIVAABRIRTESOURO))
            {
               try
               {
                  DoLockGeral();

                  Configuration.Debug("Outro Servidor pediu-me para abrir uma sala de minha responsabilidade", Configuration.PRI_MED);

                  string guidUnico = msgArranjada.guidUnico;
                  ServicosEntrada.RealizaTentativaAbrirSala(idCliente, msgArranjada.NumSala, idJogo, guidUnico);

                  //Incremento o meu relogio vectorial
                  RelogioVectorial.IncrementaServidor(ServerMain._minhaIdentificacao, ServerMain._lstRelogiosVectoriais);
                  return;
               }
               finally
               {
                  DoUnlockGeral();
               }
            }

            if (mensagem.TipoIgual(Mensagem.ENTRANOVOJOGADORNUMJOGO))
            {
               try
               {
                  DoLockGeral();
                  Configuration.Debug("Existe um novo cliente se juntou a um jogo", Configuration.PRI_MED);
                  ServicosEntrada.EntraNovoJogadorNumJogo(msgArranjada.IdJogo, msgArranjada.IdCliente);
                  return;
               }
               finally
               {
                  DoUnlockGeral();
               }
            }

            if (mensagem.TipoIgual(Mensagem.REGISTANOVOJOGADORNOSISTEMA))
            {
               try
               {
                  DoLockGeral();

                  Configuration.Debug("Existe um novo cliente que se registou no sistema", Configuration.PRI_MED);
                  ServicosEntrada.RegistaNovoJogadorNoSistema(msgArranjada.IdCliente);
                  return;
               }
               finally
               {
                  DoUnlockGeral();
               }
            }

            if (mensagem.TipoIgual(Mensagem.ADICIONANOVOJOGOSISTEMA))
            {
               try
               {
                  DoLockGeral();

                  Configuration.Debug("Existe um novo jogo no sistema", Configuration.PRI_MED);
                  ServicosEntrada.InsereNovoJogoSistema(msgArranjada.NovoJogo);
                  return;
               }
               finally
               {
                  DoUnlockGeral();
               }
            }

            if (mensagem.TipoIgual(Mensagem.AVISOSERVIDORVAISAIR))
            {
               try
               {
                  DoLockGeral();
                  Configuration.Debug("Um servidor avisou-me que vai sair do sistema", Configuration.PRI_MED);
                  ServicosEntrada.AvisoServidorVaiSair(msgArranjada._idOriginadorMensagem);
                  RelogioVectorial.IncrementaNivelTodosRelogios(ServerMain._lstRelogiosVectoriais);
                  return;
               }
               finally
               {
                  DoUnlockGeral();
               }
            }

            if (mensagem.TipoIgual(Mensagem.REMOVESERVIDORSISTEMA))
            {
               try
               {
                  DoLockGeral();

                  Configuration.Debug("Vou remover um servidor do meu sistema", Configuration.PRI_MED);
                  ServicosEntrada.RemoveServidorSistema(msgArranjada._idOriginadorMensagem, msgArranjada.NovoEstado);
                  RelogioVectorial.IncrementaNivelTodosRelogios(ServerMain._lstRelogiosVectoriais);
                  return;
               }
               finally
               {
                  DoUnlockGeral();
               }
            }

            if (mensagem.TipoIgual(Mensagem.MORREU_OUTRO_SERVIDOR))
            {
               Configuration.Debug("Fui informado que o servidor " + msgArranjada.idServidorQueMorreu + " morreu", Configuration.PRI_MED);
               ServicosEntrada.MorreuOutroServidor(msgArranjada.idServidorQueMorreu, msgArranjada.ListaJogos);
               RelogioVectorial.IncrementaNivelTodosRelogios(ServerMain._lstRelogiosVectoriais);
               //Este lock é realizado quando recebo um sinal de STOP e só o "unlocko" quando me vem o novo estado
               DoUnlockGeral();
               return;
            }

            if (mensagem.TipoIgual(Mensagem.FOSTE_CONSIDERADO_MORTO))
            {
               try
               {
                  DoLockGeral();

                  Configuration.Debug("Argh...Os outros servidores consideraram-me morto!", Configuration.PRI_MED);
                  ServicosEntrada.FuiConsideradoMorto();
                  return;
               }
               finally
               {
                  DoUnlockGeral();
               }
            }

            if (mensagem.TipoIgual(Mensagem.STOP))
            {
               //Quando recebo esta mensagem faço stop ao meu sistema e só desligo quando receber o novo estado
               DoLockGeral();
               Configuration.Debug("Recebi uma mensagem de STOP do: " + mensagem._idOriginadorMensagem, Configuration.PRI_MED);
               ServicosEntrada.TrataStop(mensagem._idOriginadorMensagem, msgArranjada.idServidorQueMorreu, msgArranjada.IdCliente, msgArranjada.IdJogo, msgArranjada.NumSala);
               return;
            }

            if (mensagem.TipoIgual(Mensagem.REPLY_STOP))
            {
               Configuration.Debug("Recebi uma mensagem de REPLY-STOP do: " + mensagem._idOriginadorMensagem, Configuration.PRI_MED);
               bool pronto = ServicosEntrada.TrataReplyStop(mensagem._idOriginadorMensagem, msgArranjada.idServidorQueMorreu);
               if (pronto)
               {
                  //Este unlockGeral recebe o IdCLiente que vai servir de flag para depois fazer unlock
                  ComunicacaoServidor.DoUnlockGeral();
                  //E vou finalmente responder ao cliente
                  RefazPedidoAberturaDoCliente(msgArranjada.IdCliente, msgArranjada.IdJogo, msgArranjada.NumSala);
               }
               return;
            }

            return;
            #endregion
             }
             Configuration.Debug("ERRO:Recebi uma mensagem que nem 'e de um cliente nem servidor Tipo --> " + mensagem.Tipo, Configuration.PRI_MAX);
        }