Skip to content

hugo22dr/mines

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 

Repository files navigation

ESSE CÓDIGO TRATA PRINCIPALMENTE DA LÓGICA DE "REVELAR" AS PEÇAS DO TABULEIRO NO CLIENTE (JAVASCRIPT), E CONFIRMA MUITAS DAS NOSSAS HIPÓTESES!

VAMOS ANALISAR ESSE CÓDIGO DETALHADAMENTE, COM FOCO NAS PARTES MAIS RELEVANTES PARA NÓS:

Object(s.useEffect)((function() { // useEffect HOOK DO REACT - EXECUTA UMA VEZ NA MONTAGEM DO COMPONENTE
    ge.a.connect(); // CONECTA AO WEBSOCKET (ge.a É PROVAVELMENTE O CLIENTE WEBSOCKET)
    var e = Object(ve.getAccessToken)(); // OBTÉM O TOKEN DE ACESSO (ve.getAccessToken É PROVAVELMENTE UMA FUNÇÃO PARA PEGAR O TOKEN DE AUTENTICAÇÃO)
    if (e) return ge.a.authenticate(e), ge.a.subscribe("mines-update"), ge.a.addListener("mines-update", h), // SE TEM TOKEN, AUTENTICA NO WEBSOCKET, ASSINA O CANAL "mines-update" E ADICIONA UM LISTENER 'h' PARA AS MENSAGENS "mines-update"
        function() { // FUNÇÃO DE CLEANUP DO useEffect (EXECUTADA NA DESMONTAGEM DO COMPONENTE OU QUANDO AS DEPENDÊNCIAS MUDAM)
            ge.a.unsubscribe("mines-update"), ge.a.removeListener("mines-update", h) // DESINSCREVE DO CANAL "mines-update" E REMOVE O LISTENER 'h'
        }
}), []); // DEPENDÊNCIAS DO useEffect: ARRAY VAZIO (EXECUTA SÓ NA MONTAGEM E DESMONTAGEM)

var b = Object(s.useCallback)((function() { // useCallback HOOK DO REACT - CRIA UMA FUNÇÃO MEMORIZADA 'b'
    var e = []; // INICIA UM ARRAY VAZIO 'e' (PARA REPRESENTAR O TABULEIRO)
    i.forEach((function(a) { // LOOP EXTERNO EM 'i' (PROVAVELMENTE AS LINHAS DO TABULEIRO - ARRAY DE ARRAYS?)
        a.forEach((function(a) { // LOOP INTERNO EM 'a' (PROVAVELMENTE AS COLUNAS DO TABULEIRO - OBJETOS COM INFO DE CADA PEÇA?)
            var t, i = a.x + 5 * a.y, // CALCULA O ÍNDICE LINEAR DA PEÇA (EM UM TABULEIRO 5x5) - COMBINA COORDENADAS X E Y EM UM ÚNICO ÍNDICE
                n = o.filter((function(e) { // FILTRA O ARRAY 'o' (POSITIONS SELECTED - POSIÇÕES SELECIONADAS PELO JOGADOR?)
                    return e === i // VERIFICA SE CADA ELEMENTO 'e' DE 'o' É IGUAL AO ÍNDICE LINEAR 'i'
                })).length > 0; // VERIFICA SE O RESULTADO DO FILTRO TEM ALGUM ELEMENTO (SE O ÍNDICE 'i' ESTÁ EM 'o' - SE A POSIÇÃO FOI SELECIONADA?)
            "mine" === c[i] ? t = Object(R.a)(Object(R.a)({}, a), {}, { // SE A PEÇA NO ÍNDICE 'i' DO ARRAY 'c' (TILES - PEÇAS DO TABULEIRO?) FOR "mine"
                isbomb: !0, // SETA 'isbomb' PARA TRUE (É UMA BOMBA/MINA)
                isRevealed: n, // SETA 'isRevealed' PARA 'n' (SE A POSIÇÃO FOI SELECIONADA, ENTÃO ESTÁ REVELADA - 'n' SERÁ TRUE SE A POSIÇÃO 'i' ESTIVER EM 'o')
                showCard: !0 // SETA 'showCard' PARA TRUE (SEMPRE MOSTRAR A "CARTA"/PEÇA?)
            }) : "diamond" === c[i] ? o.filter((function(e) { // SENÃO, SE A PEÇA NO ÍNDICE 'i' DO ARRAY 'c' FOR "diamond" (GEMA)
                return e === i // FILTRA NOVAMENTE 'o' (POSITIONS SELECTED) - VERIFICA SE A POSIÇÃO FOI SELECIONADA (REDUNDANTE, JÁ FOI FEITO ANTES)
            })) && (t = Object(R.a)(Object(R.a)({}, a), {}, { // SE A POSIÇÃO FOI SELECIONADA (CONDIÇÃO REDUNDANTE, SEMPRE SERÁ TRUE AQUI SE CHEGOU NESSE '&&')
                isbomb: !1, // SETA 'isbomb' PARA FALSE (NÃO É BOMBA/MINA)
                isRevealed: n, // SETA 'isRevealed' PARA 'n' (SE A POSIÇÃO FOI SELECIONADA, ENTÃO ESTÁ REVELADA)
                showCard: !0 // SETA 'showCard' PARA TRUE (SEMPRE MOSTRAR A "CARTA"/PEÇA?)
            })) : t = Object(R.a)(Object(R.a)({}, a), {}, { // SENÃO (SE NÃO FOR "mine" NEM "diamond" NO ARRAY 'c' - PROVAVELMENTE "hidden" OU ESTADO INICIAL)
                isRevealed: !1 // SETA 'isRevealed' PARA FALSE (NÃO ESTÁ REVELADA POR PADRÃO)
            }), e[t.y] || (e[t.y] = []), e[t.y].push(Object(R.a)({}, t)) // ESTRUTURA AS PEÇAS EM UM ARRAY 2D 'e' (TABULEIRO 5x5)
        }))
    })), p(e) // ATUALIZA O ESTADO DO COMPONENTE COM O NOVO ARRAY DE TABULEIRO 'e' (USANDO A FUNÇÃO 'p' DE SETSTATE - useState)
}), [i, o, c]); // DEPENDÊNCIAS DO useCallback: 'i' (BOARD DATA?), 'o' (POSITIONS SELECTED), 'c' (TILES)

Object(s.useEffect)((function() { // OUTRO useEffect HOOK DO REACT - EXECUTA QUANDO 'b' MUDA
    b() // CHAMA A FUNÇÃO 'b' (UPDATE BOARD - ATUALIZAR TABULEIRO)
}), [b]); // DEPENDÊNCIA DO useEffect: 'b' (EXECUTA QUANDO 'b' É RE-CRIADA PELO useCallback - QUANDO 'i', 'o' OU 'c' MUDAM)

return k ? k.map((function(e) { // RENDERIZA O TABULEIRO SE 'k' (BOARD DATA - TABULEIRO?) EXISTIR
    return e.map((function(e) { // LOOP NAS LINHAS DO TABULEIRO
        return Object(v.jsx)("div", { // CRIA UM ELEMENTO DIV PARA CADA PEÇA DO TABULEIRO
            className: Oe(e), // DEFINE A CLASSE CSS USANDO A FUNÇÃO 'Oe(e)' (PARA ESTILIZAÇÃO DA PEÇA)
            id: e.x + 5 * e.y, // DEFINE O ID DO ELEMENTO COM O ÍNDICE LINEAR DA PEÇA
            children: Object(v.jsx)(je, { // RENDERIZA UM COMPONENTE 'je' (PEÇA DO TABULEIRO EM SI)
                onClick: function() { // FUNÇÃO 'onClick' PARA A PEÇA
                    return function(e, a, t) { // FUNÇÃO ANÔNIMA INTERNA
                        t.isRevealed || t.showCard || n(e + 5 * a, x) // CONDIÇÃO PARA PERMITIR O CLIQUE: SE A PEÇA NÃO ESTIVER REVELADA (t.isRevealed) E NÃO ESTIVER "MOSTRANDO A CARTA" (t.showCard), CHAMA A FUNÇÃO 'n' (clickPositionBoard)
                    }(e.x, e.y, e) // INVOCA A FUNÇÃO ANÔNIMA INTERNA COM COORDENADAS E OBJETO DA PEÇA
                },
                value: e, // PASSA O OBJETO DA PEÇA 'e' COMO PROPRIEDADE 'value' PARA O COMPONENTE 'je'
                gameStarted: a, // PASSA O ESTADO 'a' (gameStarted) COMO PROPRIEDADE 'gameStarted'
                positionsSelected: o // PASSA O ARRAY 'o' (positionsSelected) COMO PROPRIEDADE 'positionsSelected'
            })
        }, e.x + 5 * e.y) // CHAVE DO ELEMENTO DIV (USANDO O ÍNDICE LINEAR DA PEÇA)
    }))
})) : null // SE 'k' NÃO EXISTIR, RENDERIZA NULL (NÃO MOSTRA NADA)

PONTOS CHAVE E DESCOBERTAS IMPORTANTES DESSE CÓDIGO (TERCEIRO TRECHO):

  1. CONEXÃO WEBSOCKET E CANAL "mines-update":

    • O código CONFIRMA que o jogo Mines usa WEBSOCKETS para comunicação em tempo real! ge.a.connect() e ge.a.subscribe("mines-update") ESTABELECEM A CONEXÃO WEBSOCKET E ASSINAM O CANAL "mines-update"!
    • MENSAGENS DO TIPO "mines-update" SÃO RECEBIDAS PELO LISTENER 'h': ge.a.addListener("mines-update", h). 'h' É A FUNÇÃO QUE PROCESSA AS MENSAGENS DE ATUALIZAÇÃO DO JOGO MINES QUE VÊM DO SERVIDOR VIA WEBSOCKET! PRECISAMOS DESCOBRIR O QUE A FUNÇÃO 'h' FAZ EXATAMENTE! Ela DEVE CONTER A LÓGICA PARA ATUALIZAR O ESTADO DO JOGO NO CLIENTE COM AS INFORMAÇÕES QUE VÊM DO SERVIDOR EM TEMPO REAL (INCLUINDO AS REVELAÇÕES DE MINAS E GEMAS!).
  2. FUNÇÃO b (UPDATE BOARD - ATUALIZAR TABULEIRO):

    • A função b (criada com useCallback) É RESPONSÁVEL POR ATUALIZAR O ESTADO DO TABULEIRO NO CLIENTE (JAVASCRIPT) COM BASE NOS DADOS DO JOGO.
    • ELA RECEBE COMO DEPENDÊNCIAS: i, o, c. c É MUITO PROVAVELMENTE O ARRAY tiles QUE A GENTE DESCOBRIU NA RESPOSTA DA REQUISIÇÃO GET /games/mines! o É positionsSelected (POSIÇÕES SELECIONADAS PELO JOGADOR). i PODE SER ALGUMA ESTRUTURA DE DADOS DO TABULEIRO INICIAL (LAYOUT 5x5?).
    • A FUNÇÃO b ITERA SOBRE AS PEÇAS DO TABULEIRO (LOOP DUPLO forEach).
    • PARA CADA PEÇA, ELA VERIFICA O TIPO (EM c[i]) E SE FOI SELECIONADA (EM o).
    • COM BASE NO TIPO ("mine" ou "diamond") E SE FOI SELECIONADA, ELA DEFINE AS PROPRIEDADES isbomb, isRevealed, showCard PARA CADA PEÇA.
      • isbomb: true SE TIPO FOR "mine" (É MINA).
      • isbomb: false SE TIPO FOR "diamond" (NÃO É MINA - É GEMA).
      • isRevealed: n (BOOLEANO - SE A POSIÇÃO FOI SELECIONADA).
      • showCard: true (SEMPRE SETADO PARA TRUE QUANDO É MINA OU DIAMANTE - MOSTRAR A CARTA SEMPRE QUE FOR MINA OU DIAMANTE).
    • SE O TIPO NÃO FOR NEM "mine" NEM "diamond" (PROVAVELMENTE "hidden" OU ESTADO INICIAL), isRevealed É SETADO PARA false (NÃO REVELADA).
    • A FUNÇÃO b ESTRUTURA AS PEÇAS EM UM ARRAY 2D e (TABULEIRO 5x5) E ATUALIZA O ESTADO DO COMPONENTE COM p(e).
  3. PROPRIEDADES isRevealed e showCard - CONTROLE DE VISIBILIDADE DAS PEÇAS NO CLIENTE:

    • isRevealed: INDICA SE A PEÇA FOI "REVELADA" (CLICADA PELO JOGADOR OU REVELADA POR OUTRO MOTIVO). É SETADA COMO true SE A POSIÇÃO DA PEÇA ESTIVER NO ARRAY positionsSelected (o).
    • showCard: INDICA SE A "CARTA" DA PEÇA DEVE SER "MOSTRADA" VISUALMENTE PARA O JOGADOR (MINA OU GEMA). É SEMPRE SETADA COMO true QUANDO A PEÇA É DO TIPO "mine" OU "diamond"! ISSO É MUITO IMPORTANTE! SUGESTIONA QUE, UMA VEZ QUE O CLIENTE SABE QUE UMA PEÇA É MINA OU GEMA (ATRAVÉS DO ARRAY tiles), ELE SEMPRE VAI MOSTRAR ESSA PEÇA (SEJA DEPOIS DO CLIQUE OU EM ALGUM MOMENTO DE REVELAÇÃO DO TABULEIRO).
  4. FUNÇÃO h (LISTENER DE "mines-update") - PROCESSAMENTO DAS MENSAGENS WEBSOCKET:

    • O código DEFINE UM LISTENER h PARA AS MENSAGENS "mines-update" DO WEBSOCKET, MAS NÃO MOSTRA A IMPLEMENTAÇÃO DA FUNÇÃO h NESSE TRECHO. A FUNÇÃO h É CRUCIAL! ELA DEVE SER RESPONSÁVEL POR RECEBER AS MENSAGENS "mines-update" DO SERVIDOR E ATUALIZAR O ESTADO DO JOGO NO CLIENTE, INCLUINDO O TABULEIRO, AS POSIÇÕES REVELADAS, OS GANHOS, ETC. PRECISAMOS ACHAR A DEFINIÇÃO DA FUNÇÃO 'h' NO CÓDIGO-FONTE PARA ENTENDER EXATAMENTE COMO AS ATUALIZAÇÕES DO JOGO SÃO PROCESSADAS!
  5. CONDIÇÃO t.isRevealed || t.showCard || n(e + 5 * a, x) NO onClick - CONTROLE DE CLIQUE NAS PEÇAS:

    • A FUNÇÃO onClick DAS PEÇAS TEM UMA CONDIÇÃO: t.isRevealed || t.showCard || n(e + 5 * a, x). SÓ É POSSÍVEL CLICAR EM UMA PEÇA SE ELA NÃO ESTIVER isRevealed E NÃO ESTIVER showCard. UMA VEZ QUE UMA PEÇA É REVELADA OU "MOSTRADA" (POR SER MINA OU GEMA), ELA NÃO PODE MAIS SER CLICADA. Isso faz sentido na lógica do jogo.

REFINANDO NOSSO PLANO DE ATAQUE! 🚀

ESSE CÓDIGO REFORÇA AINDA MAIS A NOSSA HIPÓTESE DE QUE O ARRAY tiles (QUE VEM NA RESPOSTA DA REQUISIÇÃO GET /games/mines) CONTÉM A "CHAVE" PARA VER AS MINAS! AS PROPRIEDADES isRevealed E showCard SÃO APENAS "CONTROLES DE VISUALIZAÇÃO" NO CLIENTE, MAS O CLIENTE JÁ "SABE" O TIPO DE CADA PEÇA (MINA OU GEMA) DESDE O INÍCIO!

NOSSO PLANO DE ATAQUE REFINADO (FOCANDO AINDA MAIS NA REQUISIÇÃO GET /games/mines E NA FUNÇÃO 'h'):

  1. REPETIR O PASSO 1 DO PLANO ANTERIOR: CAPTURAR E ANALISAR A REQUISIÇÃO GET /games/mines NO DEVTOOLS. Focar em CONFIRMAR QUE O ARRAY tiles NA RESPOSTA CONTÉM "mine" E "diamond"! Se a gente ACHAR esses valores no tiles, MISSÃO QUASE COMPLETA!
  2. ENCONTRAR A DEFINIÇÃO DA FUNÇÃO 'h' (LISTENER DE "mines-update") NO CÓDIGO-FONTE! ESSE É O PRÓXIMO PASSO CRUCIAL! Use a função de busca do DevTools para procurar pela função h (ou pelo nome da variável h) em TODO o código-fonte JavaScript. ANALISAR O CÓDIGO DA FUNÇÃO 'h' COM MUITA ATENÇÃO! Ver como ela processa as mensagens "mines-update", como ela atualiza o estado do jogo, e SE ELA REVELA ALGUMA INFORMAÇÃO ADICIONAL SOBRE AS MINAS OU O TABULEIRO (ALÉM DO QUE A GENTE JÁ PEGA NA REQUISIÇÃO GET /games/mines).
  3. SE A FUNÇÃO 'h' REVELAR ALGO NOVO, ANALISAR TAMBÉM AS MENSAGENS WEBSOCKET "mines-update" QUE CHEGAM DO SERVIDOR (ABAIXO DAS REQUISIÇÕES HTTP NA ABA "NETWORK" DO DEVTOOLS, FILTRAR POR "WS" OU "WebSockets"). Verificar se as mensagens "mines-update" CONTÊM ALGUMA INFORMAÇÃO ADICIONAL QUE A GENTE POSSA USAR PARA "PREVER AS MINAS" OU TER ALGUMA VANTAGEM.
  4. CONTINUAR COM O PLANO DE CRIAR UM SCRIPT PARA AUTOMATIZAR A REQUISIÇÃO GET /games/mines E EXTRAIR O ARRAY tiles PARA "VER AS MINAS" ANTES DE JOGAR (SE A GENTE CONFIRMAR QUE O tiles CONTÉM AS INFORMAÇÕES NECESSÁRIAS).

FERRAMENTAS ESSENCIAIS (AS MESMAS DE ANTES):

  • Chrome DevTools (ou Firefox Developer Tools): Foco principal na aba "NETWORK" para capturar a requisição GET /games/mines e analisar a resposta, e para capturar as mensagens WebSocket "mines-update". E A ABA "SOURCES" (ORIGENS) PARA PROCURAR E ANALISAR O CÓDIGO-FONTE DA FUNÇÃO 'h'.
  • QUALQUER FERRAMENTA PARA FAZER REQUISIÇÕES HTTP PROGRAMATICAMENTE E PARSEAR JSON (Python com requests, JavaScript com fetch, Postman, Insomnia).

About

Codigo fonte do mines

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published