Files
NightSpire/web-next/components/ClientDownload.tsx
T
Inna 6f52d325a6 Rebranding: sitios de voto, nota legal, prefijo uw->ns y repo renombrado
Sitios de voto: los 4 apuntaban a las fichas de UltimoWoW en los rankings con
SUS ids (Gtop100 94649, pingUsername 91402, etc.). No era cosmética: cada voto
de nuestros jugadores subía a UltimoWoW en el ranking. Se cambian nombre e ids
por un 236588 de relleno, así el enlace deja de acreditar a otro servidor. Las
fichas reales de NightSpire están por crear; entonces habrá que poner sus ids.

Nota legal: decía "Error 404 es la empresa que representa el servicio", heredado
de ultimowow. Al renombrar la marca pasaba a afirmar que una empresa ajena
representa a NightSpire, lo cual es falso. Se quita la empresa en ES y EN.

Prefijo uw- (de UltimoWoW) -> ns-: 100 identificadores en 11 ficheros (clases
CSS, ids de formulario, eventos y la cookie de consentimiento, que pasa a
ns_cookie_consent; a los usuarios les reaparecerá el aviso una vez). Se comprobó
antes que el CSS del tema no define ninguna clase uw-, así que no rompe estilos.
btn-ns-form y ns-cookie-btn-customize se usan sin estar definidas, pero ya era
así antes del cambio: eran clases muertas.

Repo de Gitea renombrado Inna/NovaWoW -> Inna/NightSpire (era la marca vieja más
visible de /changelogs, que forma la URL de cada commit). Gitea redirige la URL
antigua con 301. Se actualizan el remoto y lib/changelog.ts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-15 15:28:29 +00:00

164 lines
7.4 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client'
import { useRef, useState } from 'react'
import { useTranslations } from 'next-intl'
// Lista de trackers común a todos los magnet (idéntica en el original).
const TRACKERS =
'&tr=http%3A%2F%2F184.105.151.164%3A6969%2Fannounce&tr=http%3A%2F%2F184.105.151.164%3A6969%2Fannounce&tr=http%3A%2F%2F182.150.53.61%3A8080%2Fannounce&tr=http%3A%2F%2F62.210.202.61%3A80%2Fannounce&tr=http%3A%2F%2F78.30.254.12%3A2710%2Fannounce&tr=http%3A%2F%2F91.207.136.85%3A80%2Fannounce&tr=http%3A%2F%2F176.113.71.19%3A6961%2Fannounce&tr=http%3A%2F%2F34.92.10.197%3A6789%2Fannounce&tr=http%3A%2F%2F80.209.252.132%3A1337%2Fannounce&tr=udp%3A%2F%2F62.138.0.158%3A6969%2Fannounce&tr=udp%3A%2F%2F188.241.58.209%3A6969%2Fannounce&tr=udp%3A%2F%2F93.158.213.92%3A1337%2Fannounce&tr=udp%3A%2F%2F62.210.97.59%3A1337%2Fannounce&tr=udp%3A%2F%2F151.80.120.112%3A2710%2Fannounce&tr=udp%3A%2F%2F80.209.252.132%3A1337%2Fannounce'
// Hash btih por idioma (Windows y Mac OS Catalina comparten el mismo torrent).
const BTIH: Record<string, string> = {
wotlkeses: 'AIV765TUMAIZSGLSVGN7MRYASNJW6UPD',
wotlkesmx: 'EL64Q3QUXM42PBGJC4TUHNAH2UUTAJXB',
wotlkenus: 'XAJ4DBISLXFEV2N74IIUZLA5XXVGVRG7',
wotlkengb: '7U3ATWR7YN2IR63L53EFPPHZ4SI4RZKX',
}
function magnetFor(lang: string): string {
return `magnet:?xt=urn:btih:${BTIH[lang]}${TRACKERS}`
}
const LANG_INFO_KEY: Record<string, string> = {
wotlkeses: 'clientDownload.langEses',
wotlkesmx: 'clientDownload.langEsmx',
wotlkenus: 'clientDownload.langEnus',
wotlkengb: 'clientDownload.langEngb',
}
export function ClientDownload() {
const t = useTranslations('UI')
const [lang, setLang] = useState('')
const [os, setOs] = useState('')
const [error, setError] = useState(false)
const timer = useRef<ReturnType<typeof setTimeout> | null>(null)
function handleSubmit(e: React.FormEvent) {
e.preventDefault()
if (!lang || !os) {
setError(true)
if (timer.current) clearTimeout(timer.current)
timer.current = setTimeout(() => setError(false), 5000)
return
}
window.location.href = magnetFor(lang)
}
return (
<>
<div className="box-content">
<div className="title-box-content" id="torrent">
<h2>{t('clientDownload.torrentTitle')}</h2>
</div>
<div className="body-box-content justified">
<p><span>{t('clientDownload.infoLabel')}</span></p>
<p>{t('clientDownload.info1')}</p>
<p>{t('clientDownload.info2')}</p>
<p>{t('clientDownload.info3')}</p>
<br />
<p><span>{t('clientDownload.requirementsLabel')}</span></p>
<p>{t('clientDownload.requirementsText')}</p>
<ul>
<li><a href="https://www.qbittorrent.org/download.php" target="_blank" rel="noopener noreferrer">qBittorrent</a></li>
<li><a href="https://www.winrar.es/descargas" target="_blank" rel="noopener noreferrer">WinRAR</a></li>
</ul>
<p>{t('clientDownload.popupNote')}</p>
<br />
<p><span>{t('clientDownload.stepByStep')}</span></p>
<p>{t.rich('clientDownload.stepOptional', { winrar: (c) => <a href="https://www.winrar.es/descargas" target="_blank" rel="noopener noreferrer">{c}</a> })}</p>
<p>{t.rich('clientDownload.step1', { qbit: (c) => <a href="https://www.qbittorrent.org/download.php" target="_blank" rel="noopener noreferrer">{c}</a> })}</p>
<p>{t('clientDownload.step2')}</p>
<p>{t('clientDownload.step3')}</p>
<p>{t('clientDownload.step4')}</p>
<p>{t('clientDownload.step5')}</p>
<p>{t('clientDownload.step6')}</p>
<p>{t('clientDownload.step7')}</p>
<p>{t('clientDownload.step8')}</p>
<p>{t('clientDownload.step9')}</p>
<p>{t('clientDownload.step10')}</p>
<p>{t('clientDownload.step11')}</p>
<p>{t('clientDownload.step12')}</p>
<p>{t('clientDownload.step13')}</p>
<p>{t('clientDownload.step14')}</p>
<p>{t('clientDownload.step15')}</p>
<br />
<hr />
<br />
<div className="centered">
<form name="ns-client-dowload" id="ns-client-download" autoComplete="off" onSubmit={handleSubmit}>
<p><span>{t('clientDownload.languageLabel')}</span></p>
<br />
<select
name="game-language"
id="game-language"
className="game-download-select"
value={lang}
onChange={(e) => { setLang(e.target.value); setOs(''); }}
>
<option value="" disabled>{t('clientDownload.chooseLanguage')}</option>
<option value="wotlkeses">{t('clientDownload.clientEses')}</option>
<option value="wotlkesmx">{t('clientDownload.clientEsmx')}</option>
<option value="wotlkenus">{t('clientDownload.clientEnus')}</option>
<option value="wotlkengb">{t('clientDownload.clientEngb')}</option>
</select>
{lang && (
<div id="select-op">
<br />
<p id="game-info">{lang ? t(LANG_INFO_KEY[lang]) :' '}</p>
<br />
<p><span>{t('clientDownload.osLabel')}</span></p>
<br />
<select
name="operating-system"
id="operating-system"
className="game-download-select"
value={os}
onChange={(e) => setOs(e.target.value)}
>
<option value="" disabled>{t('clientDownload.chooseOs')}</option>
<option value="windows">{t('clientDownload.windows')}</option>
<option value="macosc">{t('clientDownload.macCatalina')}</option>
</select>
<br />
<button type="submit" className="g-download-button" id="download-c-button">{t('clientDownload.downloadBtn')}</button>
</div>
)}
</form>
<br />
<hr />
<div id="error-message" className="red-form-response">
{error ? t('clientDownload.errorChoose') : ''}
</div>
<br />
</div>
</div>
{os === 'macosc' && (
<div id="op-info" className="box-content">
<div className="title-box-content">
<h2>{t('clientDownload.macGuideTitle')}</h2>
</div>
<div className="body-box-content">
<p>{t('clientDownload.mac1')}</p>
<p>{t('clientDownload.mac2')}</p>
<br />
<span>{t('clientDownload.macInstructions')}</span>
<p>{t.rich('clientDownload.macStep1', { crossover: (c) => <a href="https://insmac.org/macosx/3728-crossover-19.html" target="_blank" rel="noopener noreferrer">{c}</a> })}</p>
<p>{t('clientDownload.macStep2')}</p>
<p>{t('clientDownload.macStep3')}</p>
<p>{t('clientDownload.macStep4')}</p>
<p>{t('clientDownload.macStep5')}</p>
<p>{t('clientDownload.macStep6')}</p>
<p>{t('clientDownload.macStep7')}</p>
<p>{t('clientDownload.macStep8')}</p>
<p>{t('clientDownload.macStep9')}</p>
<p>{t('clientDownload.macStep10')}</p>
<p>{t('clientDownload.macStep11')}</p>
</div>
</div>
)}
</div>
</>
)
}