Данные из интернета
Прогноз погоды, таблица лиги, оповещения стрима: оверлей может обращаться к адресам, которые назвал, когда игрок согласится.
Укажите адреса в манифесте
Оверлей обращается только к Racelink, пока его манифест не назовёт адреса, а игрок их не разрешит (Безопасность):
"permissions": { "internet": ["api.example.com", "*.cdn.example.com"] }- До 20 адресов.
*.example.comпокрывает все поддомены. - Только имена хостов: без схемы, порта, пути, IP-адреса и локальных имён.
- По HTTPS и WSS:
fetch,WebSocket, а также картинки, медиа и шрифты с этих адресов. - Скрипты по-прежнему грузятся только из вашего пакета, какие бы адреса ни были.
Доступ разрешает игрок
Игрок видит адреса, когда добавляет оверлей, и может отказать. Может и передумать позже; тогда Racelink перезагружает оверлей, чтобы тот начал с новыми правилами. Новая версия, добавившая адрес, спрашивает снова, и новый адрес закрыт, пока игрок не согласится.
Оверлей должен работать и без интернета
overlay.permissions.internet говорит, открыты ли адреса. Проверяйте его перед запросом и показывайте что-то полезное, когда они закрыты:
const loadForecast = async (): Promise<void> => {
if (!overlay.permissions.internet) {
forecast.textContent = 'Прогноз выключен';
return;
}
try {
const response = await fetch('https://api.example.com/forecast?track=' + trackId);
if (!response.ok) throw new Error(String(response.status));
showForecast(await response.json());
} catch {
forecast.textContent = 'Нет прогноза';
}
};export function Forecast({ overlay, trackId }: ForecastProps) {
const [data, setData] = useState<ForecastData | null>(null);
const allowed = overlay.permissions.internet;
useEffect(() => {
if (!allowed) return;
const controller = new AbortController();
fetch('https://api.example.com/forecast?track=' + trackId, { signal: controller.signal })
.then((response) => (response.ok ? response.json() : null))
.then(setData)
.catch(() => setData(null));
return () => controller.abort();
}, [allowed, trackId]);
if (!allowed) return <p className="forecast">Прогноз выключен</p>;
return data ? <ForecastView data={data} /> : <p className="forecast">Нет прогноза</p>;
}Во время разработки страница идёт с вашего dev-сервера, и браузер применяет правила вашего сервера, а не оверлея: адрес, которого нет в манифесте, у вас работает, а у игроков — нет. Держите список в манифесте полным.