{"id":16,"date":"2025-11-16T19:55:38","date_gmt":"2025-11-16T22:55:38","guid":{"rendered":"https:\/\/zonafranga.servegame.com\/?page_id=16"},"modified":"2026-04-15T07:51:13","modified_gmt":"2026-04-15T10:51:13","slug":"quebra-galo","status":"publish","type":"page","link":"https:\/\/zonafranga.servegame.com\/?page_id=16","title":{"rendered":"Quebra Galo"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"576\" src=\"https:\/\/zonafranga.servegame.com\/wp-content\/uploads\/2025\/11\/qg-1024x576.jpg\" alt=\"\" class=\"wp-image-193\" srcset=\"https:\/\/zonafranga.servegame.com\/wp-content\/uploads\/2025\/11\/qg-1024x576.jpg 1024w, https:\/\/zonafranga.servegame.com\/wp-content\/uploads\/2025\/11\/qg-300x169.jpg 300w, https:\/\/zonafranga.servegame.com\/wp-content\/uploads\/2025\/11\/qg-768x432.jpg 768w, https:\/\/zonafranga.servegame.com\/wp-content\/uploads\/2025\/11\/qg-1536x864.jpg 1536w, https:\/\/zonafranga.servegame.com\/wp-content\/uploads\/2025\/11\/qg-2048x1152.jpg 2048w, https:\/\/zonafranga.servegame.com\/wp-content\/uploads\/2025\/11\/qg-500x281.jpg 500w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>O Quebra Galo possui as mesmas funcionalidades e regras gerais de conduta do Zona Franga, sendo que ser\u00e1 utilizado preferencialmente no modo Duel.<\/p>\n\n\n\n<p>Uma particularidade do Quebra Galo \u00e9 o HUD dos jogadores que fica aberto para os espectadores, al\u00e9m do auto-balance e tempo de inatividade que ficam desabilitados. O chat do jogo \u00e9 vis\u00edvel para a comunidade no canal \u2060chat_qg no nosso Discord, sendo permitido inclusive a intera\u00e7\u00e3o reversa a partir dos usu\u00e1rios do Discord para os jogadores conectados no servidor.<\/p>\n\n\n\n<p><strong>Obs:<\/strong> Caso algum mapa adequado para duelo n\u00e3o esteja dispon\u00edvel, basta solicitar a inclus\u00e3o para que seja avaliado<\/p>\n\n\n\n<style>\n\/* ================================================================\n   WRAPPER \u2014 impede o estilo de vazar para o resto do site\n   ================================================================ *\/\n#status-wrapper {\n  background: transparent !important;\n  padding: 0 !important;\n  border-radius: 0 !important;\n}\n\n#status-wrapper,\n#status-wrapper * {\n  font-family: \"Consolas\", \"Courier New\", monospace !important;\n  box-sizing: border-box;\n}\n\n\/* ================================================================\n   CONTORNO PARA TEXTOS JKA (hostname colorido)\n   ================================================================ *\/\n.jka-colored {\n  -webkit-text-stroke: 0.6px #000 !important;\n  text-shadow: 1px 1px 2px #000 !important;\n}\n\n\/* ================================================================\n   GRID DOS SERVIDORES\n   ================================================================ *\/\n#status-wrapper #servers {\n  display: grid;\n  grid-template-columns: repeat(auto-fit, minmax(650px, 1fr));\n  gap: 24px;\n  padding-left: 40px;\n  justify-content: center;\n  justify-items: center;\n  max-width: 900px;\n  margin: 10px auto 0 auto;\n}\n\n#status-wrapper #titulo-status {\n  display: none;\n}\n\n\/* ================================================================\n   CARD DO SERVIDOR (online ou offline)\n   ================================================================ *\/\n#status-wrapper .server-card {\n  background: url(\"\/maps\/fundo.jpg\");\n  background-size: cover;\n  background-position: center;\n  background-repeat: no-repeat;\n  color: #f1f1f1;\n  border-radius: 14px;\n  overflow: hidden;\n  transition: transform 0.25s ease, box-shadow 0.25s ease;\n  display: flex;\n  flex-direction: row;\n  align-items: stretch;\n  border: 2px solid #555;\n  position: relative;\n}\n\n#status-wrapper .server-card:hover {\n  transform: translateY(-4px);\n}\n\n\/* ================================================================\n   \u00c1REA DE INFORMA\u00c7\u00d5ES DO SERVIDOR\n   ================================================================ *\/\n#status-wrapper .server-info {\n  padding: 12px 16px;\n  flex: 1;\n  text-align: left;\n  display: flex;\n  flex-direction: column;\n  align-items: flex-start;\n}\n\n#status-wrapper .server-info h3 {\n  margin-bottom: 20px;\n  font-size: 14px;\n  font-weight: bold;\n  -webkit-text-stroke: 2px #fff;\n  background-color: rgba(100, 100, 100, 0.5);\n  padding: 4px 8px;\n  border-radius: 6px;\n  display: inline-block;\n}\n\n#status-wrapper .server-info p {\n  margin: 6px 0 !important;\n}\n\n#status-wrapper .server-info strong {\n  color: #cc6600 !important;\n  text-transform: uppercase;\n  font-weight: bold;\n}\n\n#status-wrapper .server-info span.value {\n  color: #fff;\n}\n\n#status-wrapper .server-info h3,\n#status-wrapper .server-info h3 span {\n  text-transform: none !important;\n}\n\n\/* ================================================================\n   IMAGEM DO MAPA\n   ================================================================ *\/\n#status-wrapper .server-map {\n  width: 70%;\n  max-width: 300px;\n  height: auto;\n  object-fit: contain;\n  border-radius: 10px;\n  margin-right: 16px;\n  margin-left: auto;\n}\n\n\/* ================================================================\n   BOT\u00c3O DETALHES\n   ================================================================ *\/\n#status-wrapper .details-btn {\n  display: inline-block;\n  margin-top: 15px;\n  padding: 8px 16px;\n  background: #444 !important;\n  color: #fff !important;\n  border: 1px solid #888;\n  border-radius: 6px;\n  cursor: pointer;\n  font-size: 14px;\n  transition: background 0.2s ease, transform 0.2s ease;\n  align-self: center;\n  width: 120px;\n}\n\n#status-wrapper .details-btn:hover {\n  background: #666 !important;\n  transform: scale(1.05);\n}\n\n\/* ================================================================\n   RODAP\u00c9\n   ================================================================ *\/\n#status-wrapper #last-update {\n  margin-top: 20px;\n  color: #aaa;\n  font-size: 15px;\n}\n\n\/* ================================================================\n   MODAL \u2014 jogadores conectados\n   ================================================================ *\/\n#status-wrapper .modal {\n  position: fixed;\n  top: 50%;\n  left: 50%;\n  transform: translate(-50%, -50%);\n  background: #222;\n  border-radius: 10px;\n  padding: 20px;\n  display: none;\n  z-index: 1000;\n  width: 300px;\n}\n\n#status-wrapper .modal table {\n  width: 100%;\n  border-collapse: collapse;\n  color: #ddd;\n}\n\n#status-wrapper .modal th,\n#status-wrapper .modal td {\n  text-align: left;\n  padding: 4px 6px;\n}\n\n#status-wrapper .modal th {\n  font-weight: bold;\n  color: #fff;\n  border-bottom: 1px solid #444;\n}\n\n#status-wrapper .modal tr:nth-child(even) {\n  background: #2a2a2a;\n}\n\n#status-wrapper .modal-close {\n  margin-top: 10px;\n  padding: 5px 10px;\n  background: #555;\n  border-radius: 6px;\n  color: #fff;\n  cursor: pointer;\n}\n\n#status-wrapper .modal-close:hover {\n  background: #777;\n}\n\n\/* ================================================================\n   MOBILE\n   ================================================================ *\/\n@media (max-width: 640px) {\n\n  #status-wrapper #servers {\n    grid-template-columns: 1fr !important;\n    padding-left: 0 !important;\n  }\n\n  #status-wrapper .server-card {\n    flex-direction: column !important;\n    align-items: center !important;\n    background-image: url(\"\/maps\/fundo2.jpg\") !important;\n  }\n\n  #status-wrapper .server-map {\n    display: none !important;\n  }\n\n  #status-wrapper .server-info {\n    width: 100% !important;\n    padding: 16px !important;\n  }\n\n  #status-wrapper .server-card .server-info h3 {\n    font-size: 12px !important;\n    line-height: 1.2 !important;\n  }\n\n  \/* \ud83d\udd11 AQUI est\u00e1 o ponto correto *\/\n  #status-wrapper .jka-colored {\n    -webkit-text-stroke: 0 !important;\n    text-shadow: none !important;\n    \/* N\u00c3O definir color aqui *\/\n  }\n}\n\n<\/style>\n\n<!-- ================================================================\n     HTML PRINCIPAL\n   ================================================================ -->\n<div id=\"status-wrapper\">\n  <div id=\"servers\"><\/div>\n  <div id=\"last-update\"><\/div>\n\n  <!-- Modal -->\n  <div id=\"modal\" class=\"modal\">\n    <table id=\"players-table\">\n      <thead>\n        <tr><th>Jogadores<\/th><th>Ping<\/th><\/tr>\n      <\/thead>\n      <tbody><\/tbody>\n    <\/table>\n    <button class=\"modal-close\" onclick=\"fecharModal()\">Fechar<\/button>\n  <\/div>\n\n<script>\n\/* ================================================================\n   Fun\u00e7\u00e3o para aplicar cores JKA (^1 ^2 ^3 ...)\n   ================================================================ *\/\nfunction jkaColor(text) {\n  if (!text) return '';\n  const colors = {\n    0: '#000000', 1: '#ff0000', 2: '#00ff00', 3: '#ffff00',\n    4: '#0000ff', 5: '#00ffff', 6: '#ff00ff', 7: '#ffffff',\n    8: '#ff7f00', 9: '#7f7f7f'\n  };\n  return text\n    .replace(\/\\^(.)\/g, (_, code) => {\n      const color = colors[code] || '#ffffff';\n      return `<\/span><span class=\"jka-colored\" style=\"color:${color}\">`;\n    })\n    .replace(\/^\/, '<span class=\"jka-colored\" style=\"color:#ffffff\">') + '<\/span>';\n}\n\n\/* ================================================================\n   Modal\n   ================================================================ *\/\nfunction abrirModal(jogadores) {\n  const modal = document.getElementById(\"modal\");\n  const tbody = document.querySelector(\"#players-table tbody\");\n  tbody.innerHTML = \"\";\n\n  if (jogadores?.length) {\n    jogadores.forEach(j => {\n      const tr = document.createElement(\"tr\");\n      tr.innerHTML = `<td class=\"jka-colored\">${jkaColor(j.name || \"\")}<\/td><td>${j.ping}<\/td>`;\n      tbody.appendChild(tr);\n    });\n  } else {\n    tbody.innerHTML = \"<tr><td colspan='2'>Nenhum jogador no momento<\/td><\/tr>\";\n  }\n\n  modal.style.display = \"block\";\n}\n\nfunction fecharModal() {\n  document.getElementById(\"modal\").style.display = \"none\";\n}\n\n\/* ================================================================\n   Nomes fake quando offline\n   ================================================================ *\/\nconst offlineNames = {\n  29070: \"!^0SA ^8ZONA FRANGA ^2[OPEN\/FA]\",\n  29071: \"!^0SA ^8QUEBRA GALO ^3[DUEL\/FA]\",\n  29072: \"!^0SA ^8LUTA FRANGA ^6[LEGS\/FA]\",\n  29073: \"!^0SA ^8COCOCO RICO ^4[DEV MAP]\",\n  29074: \"!^0SA ^8GALO OCULTO ^9[UNLISTD]\",\n  29075: \"!^0SA ^8COCOCOLISEU ^1[PRIVATE]\"\n};\n\n\/* ================================================================\n   FUN\u00c7\u00d5ES DE NETWORK (retry + timeout)\n   ================================================================ *\/\nfunction fetchTimeout(url, timeout = 4000) {\n  return Promise.race([\n    fetch(url, { cache: \"no-store\" }),\n    new Promise((_, rej) => setTimeout(() => rej(new Error(\"timeout\")), timeout))\n  ]);\n}\n\nasync function fetchWithRetry(url, tentativas = 2) {\n  for (let i = 0; i < tentativas; i++) {\n    try {\n      const r = await fetchTimeout(url);\n      if (!r.ok) throw new Error(\"Erro HTTP\");\n      const j = await r.json();\n      return j;\n    } catch (e) {\n      if (i === tentativas - 1) throw e;\n      await new Promise(res => setTimeout(res, 1200));\n    }\n  }\n}\n\n\/* ================================================================\n   Carregar servidores + valida\u00e7\u00e3o de JSON\n   ================================================================ *\/\nasync function carregarServidores() {\n  const container = document.getElementById(\"servers\");\n  const lastUpdate = document.getElementById(\"last-update\");\n  container.innerHTML = \"<p>\u23f3 Carregando...<\/p>\";\n\n  try {\n    \/* ----- FETCH COM RETRY ----- *\/\n    const data = await fetchWithRetry(\"\/servers.json?cachebuster=\" + Date.now(), 2);\n\n    container.innerHTML = \"\";\n\n    \/* ----- VALIDA\u00c7\u00c3O DO JSON ----- *\/\n    if (!data || !Array.isArray(data.servers) || data.servers.length === 0) {\n      lastUpdate.textContent = \"\u26a0\ufe0f Tentando novamente...\";\n      return setTimeout(carregarServidores, 1500);\n    }\n\n\/* ===== FILTRO PARA MOSTRAR APENAS OPEN (29070) E INVS (29074) ===== *\/\ndata.servers = data.servers.filter(s => s.port === 29071);\n\n    \/* ----- LOOP DOS SERVIDORES ----- *\/\n    data.servers.forEach(s => {\n      const isOnline = s.status?.serverInfo;\n      const card = document.createElement(\"div\");\n      card.className = \"server-card\";\n\n      \/* ------------------------- ONLINE ------------------------- *\/\n      if (isOnline) {\n        const info = s.status.serverInfo;\n        const hostname = jkaColor(info.sv_hostname);\n        const locked = info.g_needpass === \"1\" ? \" <span style='font-size:14px;color:#bbb;'>\ud83d\udd12<\/span>\" : \"\";\n        const icon = \"\ud83d\udfe2\";\n        const mapname = info.mapname;\n        const players = `${(s.status.players || []).length}\/${info.sv_maxclients || 0}`;\n\n        const ddns = `zonafranga.servegame.com:${s.port}`;\n\n        let modo = \"Desconhecido\";\n        switch(info.g_Authenticity) {\n          case \"0\": modo = \"Open\"; break;\n          case \"1\": modo = \"Semi-Authentic\"; break;\n          case \"2\": modo = \"Full-Authentic\"; break;\n          case \"3\": modo = \"Duel\"; break;\n          case \"4\": modo = \"Legends\"; break;\n        }\n\n        const infoDiv = document.createElement(\"div\");\n        infoDiv.className = \"server-info\";\n        infoDiv.innerHTML = `\n          <h3>${icon} ${hostname}${locked}<\/h3>\n          <p><strong>IP:<\/strong> <span class=\"value\">${ddns}<\/span><\/p>\n          <p><strong>VERS\u00c3O:<\/strong> <span class=\"value\">${info.gamename}<\/span><\/p>\n          <p><strong>MAPA:<\/strong> <span class=\"value\">${mapname}<\/span><\/p>\n          <p><strong>MODO:<\/strong> <span class=\"value\">${modo}<\/span><\/p>\n          <p><strong>JOGADORES:<\/strong> <span class=\"value\">${players}<\/span><\/p>\n          <button class=\"details-btn\" data-online=\"1\">DETALHES<\/button>\n        `;\n\n        infoDiv.querySelector(\".details-btn\").onclick =\n          () => abrirModal(s.status.players || []);\n\n        const mapImg = document.createElement(\"img\");\n        mapImg.className = \"server-map\";\n        mapImg.src = `\/maps\/${mapname.toLowerCase()}.jpg`;\n        mapImg.onerror = () => mapImg.src = \"\/maps\/default.jpg\";\n\n        card.appendChild(infoDiv);\n        card.appendChild(mapImg);\n        container.appendChild(card);\n      }\n\n      \/* ------------------------- OFFLINE ------------------------- *\/\n      else {\n        const hostname = jkaColor(offlineNames[s.port]);\n        const icon = \"\ud83d\udd34\";\n        const ddns = `zonafranga.servegame.com:${s.port}`;\n\n        const infoDiv = document.createElement(\"div\");\n        infoDiv.className = \"server-info\";\n        infoDiv.innerHTML = `\n          <h3>${icon} ${hostname}<\/h3>\n          <p><strong>IP:<\/strong> <span class=\"value\">${ddns}<\/span><\/p>\n          <p><strong>VERS\u00c3O:<\/strong> <span class=\"value\">-<\/span><\/p>\n          <p><strong>MAPA:<\/strong> <span class=\"value\">-<\/span><\/p>\n          <p><strong>MODO:<\/strong> <span class=\"value\">-<\/span><\/p>\n          <p><strong>JOGADORES:<\/strong> <span class=\"value\">-<\/span><\/p>\n          <button class=\"details-btn\" data-online=\"0\">DETALHES<\/button>\n        `;\n\n        const mapImg = document.createElement(\"img\");\n        mapImg.className = \"server-map\";\n        mapImg.src = \"\/maps\/default.jpg\";\n\n        card.appendChild(infoDiv);\n        card.appendChild(mapImg);\n        container.appendChild(card);\n      }\n    });\n\n    \/* \u00daltima atualiza\u00e7\u00e3o *\/\n    if (data.last_update) {\n      const date = new Date(data.last_update * 1000);\n      lastUpdate.textContent = `\ud83d\udd52 Atualizado em: ${date.toLocaleString(\"pt-BR\")}`;\n    }\n\n  } catch (e) {\n    container.innerHTML = \"<p>\u274c Erro ao carregar status.<\/p>\";\n    console.error(e);\n  }\n}\n\n\/* ================================================================\n   MODAL para servidores offline\n   ================================================================ *\/\ndocument.addEventListener(\"click\", function(e) {\n  if (!e.target.classList.contains(\"details-btn\")) return;\n\n  if (e.target.dataset.online === \"1\") return;\n\n  const modal = document.getElementById(\"modal\");\n  const tbody = document.querySelector(\"#players-table tbody\");\n  tbody.innerHTML = \"<tr><td colspan='2'>Servidor offline \u2013 detalhes indispon\u00edveis<\/td><\/tr>\";\n  modal.style.display = \"block\";\n});\n\n\/* ================================================================\n   Inicializa\u00e7\u00e3o + atualiza\u00e7\u00e3o autom\u00e1tica\n   ================================================================ *\/\nasync function loopAtualizacao() {\n  await carregarServidores();\n  setTimeout(loopAtualizacao, 60000);\n}\n\nloopAtualizacao();\n\n<\/script>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>O Quebra Galo possui as mesmas funcionalidades e regras gerais de conduta do Zona Franga, sendo que ser\u00e1 utilizado preferencialmente no modo Duel. Uma particularidade do Quebra Galo \u00e9 o HUD dos jogadores que fica aberto para os espectadores, al\u00e9m &hellip; <a href=\"https:\/\/zonafranga.servegame.com\/?page_id=16\">Continue lendo <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-16","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/zonafranga.servegame.com\/index.php?rest_route=\/wp\/v2\/pages\/16","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zonafranga.servegame.com\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/zonafranga.servegame.com\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/zonafranga.servegame.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zonafranga.servegame.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=16"}],"version-history":[{"count":16,"href":"https:\/\/zonafranga.servegame.com\/index.php?rest_route=\/wp\/v2\/pages\/16\/revisions"}],"predecessor-version":[{"id":512,"href":"https:\/\/zonafranga.servegame.com\/index.php?rest_route=\/wp\/v2\/pages\/16\/revisions\/512"}],"wp:attachment":[{"href":"https:\/\/zonafranga.servegame.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=16"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}