MediaWiki:Common.js: различия между версиями
Материал из Space Station 14 Вики
Kerisar (обсуждение | вклад) мНет описания правки |
Kerisar (обсуждение | вклад) мНет описания правки |
||
| Строка 1: | Строка 1: | ||
const IFRAME_CONFIG = { | const IFRAME_CONFIG = { | ||
iframe1: { | |||
src: 'https://example.com', | |||
srcdoc: '', | |||
width: '600', | |||
height: '400', | |||
name: 'iframe1', | |||
allow: 'clipboard-write', | |||
referrerpolicy: 'no-referrer', | |||
sandbox: 'allow-same-origin', | |||
id: 'iframe1' | |||
}, | |||
iframe2: { | |||
src: '', | |||
srcdoc: '<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Bootstrap demo</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"><script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script></head><body><form><div class="mb-3"><label for="exampleInputEmail1" class="form-label">Email address</label><input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp"><div id="emailHelp" class="form-text">We ll never share your email with anyone else.</div></div><div class="mb-3"><label for="exampleInputPassword1" class="form-label">Password</label><input type="password" class="form-control" id="exampleInputPassword1"></div><div class="mb-3 form-check"><input type="checkbox" class="form-check-input" id="exampleCheck1"><label class="form-check-label" for="exampleCheck1">Check me out</label></div><button type="submit" class="btn btn-primary">Submit</button></form></body></html>', | |||
width: '600', | |||
height: '400', | |||
name: 'iframe2', | |||
allow: '', | |||
referrerpolicy: '', | |||
sandbox: '', | |||
id: 'iframe2' | |||
} | |||
}; | }; | ||
const currentURL = window.location.href; | const currentURL = window.location.href; | ||
const serversStatus = [{ | const serversStatus = [{ | ||
name: "server-main", | |||
connect: "https://game2.station14.ru/main/server/status", | |||
serverconnect: "game2.station14.ru/main/server" | |||
}, { | }, { | ||
name: "server-nova", | |||
connect: "https://game2.station14.ru/nova/server/status", | |||
serverconnect: "game2.station14.ru/nova/server" | |||
}, { | }, { | ||
name: "server-athara", | |||
connect: "https://game2.station14.ru/athara/server/status", | |||
serverconnect: "game2.station14.ru/athara/server" | |||
}, { | }, { | ||
name: "server-solaris", | |||
connect: "https://game2.station14.ru/solaris/server/status", | |||
serverconnect: "game2.station14.ru/solaris/server" | |||
}, { | }, { | ||
name: "server-echo", | |||
connect: "https://game2.station14.ru/echo/server/status", | |||
serverconnect: "game2.station14.ru/echo/server" | |||
}, { | }, { | ||
name: "server-elysium", | |||
connect: "https://game2.station14.ru/elysium/server/status", | |||
serverconnect: "game2.station14.ru/elysium/server" | |||
}, { | }, { | ||
name: "server-nebula", | |||
connect: "https://game2.station14.ru/nebula/server/status", | |||
serverconnect: "game2.station14.ru/nebula/server" | |||
}, { | }, { | ||
name: "server-wl", | |||
connect: "https://game2.station14.ru/wl/server/status", | |||
serverconnect: "game2.station14.ru/wl/server" | |||
}, { | }, { | ||
name: "server-frontier", | |||
connect: "https://api.codetabs.com/v1/proxy/?quest=https://arles.station14.ru/frontier-main/server/status", | |||
serverconnect: "arles.station14.ru/frontier-main/server" | |||
}, { | }, { | ||
name: "server-fallout", | |||
connect: "https://api.codetabs.com/v1/proxy/?quest=http://188.92.78.98:1221/status", | |||
serverconnect: "188.92.78.98:1221" | |||
}, { | }, { | ||
name: "server-marines", | |||
connect: "https://game1.station14.ru/marines-main/server/status", | |||
serverconnect: "game1.station14.ru/marines-main/server" | |||
}, { | }, { | ||
name: "server-stalker", | |||
connect: "https://api.codetabs.com/v1/proxy/?quest=https://game.stalkers14.xyz/status", | |||
serverconnect: "game.stalkers14.xyz" | |||
}]; | }]; | ||
function getXHRInfo(url) { | function getXHRInfo(url) { | ||
return new Promise(function(resolve, reject) { | |||
var xhr = new XMLHttpRequest(); | |||
xhr.open('GET', url, true); | |||
xhr.onload = function() { | |||
if (xhr.status >= 200 && xhr.status < 300) { | |||
resolve(JSON.parse(xhr.responseText)); | |||
} else { | |||
reject('Ошибка при выполнении запроса: ' + xhr.status); | |||
} | |||
}; | |||
xhr.onerror = function() { | |||
reject('Ошибка при выполнении запроса'); | |||
}; | |||
xhr.send(); | |||
}); | |||
} | } | ||
function updateServerInfoByConnect(connect, name) { | function updateServerInfoByConnect(connect, name) { | ||
getServerTime().then(function(currentUnixTime) { | |||
return getXHRInfo(connect).then(function(serverData) { | |||
var unixStartRound = getUnixTime(serverData.round_start_time); | |||
var timeDisplay = unixStartRound ? secondsToDHM(currentUnixTime - | |||
unixStartRound) : "–"; | |||
var currentPlayers = serverData.players; | |||
var maxPlayers = serverData.soft_max_players; | |||
// Вычисляем процент | |||
var percentage = maxPlayers > 0 ? Math.round((currentPlayers / | |||
maxPlayers) * 100) : 0; | |||
// Форматируем строку с количеством игроков | |||
var playersDisplay = currentPlayers && maxPlayers ? currentPlayers + '/' + | |||
maxPlayers : "–"; | |||
// Функция для проверки на пустые данные | |||
function checkValue(value) { | |||
return value ? value : "–"; | |||
} | |||
var serverInfo = { | |||
name: checkValue(serverData.name), | |||
round: checkValue(serverData.round_id), | |||
status: checkValue(serverData.run_level), | |||
map: checkValue(serverData.map), | |||
time: timeDisplay, | |||
players: playersDisplay, | |||
preset: checkValue(serverData.preset), | |||
percentage: percentage | |||
}; | |||
updateServerInfo(serverInfo, name); | |||
//console.log("serverInfo", serverInfo, "currentUnixTime", currentUnixTime,"unixStartRound", unixStartRound); | |||
}); | |||
}).catch(function(error) { | |||
console.error(error); | |||
}); | |||
} | } | ||
function getUnixTime(dateString) { | function getUnixTime(dateString) { | ||
return Math.floor(new Date(dateString).getTime() / 1000); // Делим на 1000, чтобы получить секунды | |||
} | } | ||
function secondsToDHM(seconds) { | function secondsToDHM(seconds) { | ||
var days = Math.floor(seconds / 86400); | |||
var hours = Math.floor((seconds % 86400) / 3600); | |||
var minutes = Math.floor((seconds % 3600) / 60); | |||
var result = ""; | |||
if (days > 0) result += days + " дн, "; | |||
if (hours > 0) result += hours + " ч "; | |||
// Проверка на наличие минут | |||
if (minutes > 0) { | |||
result += minutes + " мин"; | |||
} else { | |||
result += "–"; // Символ ожидания, если минут нет | |||
} | |||
return result.trim(); | |||
} | } | ||
function getServerTime() { | function getServerTime() { | ||
return fetch( | |||
'https://station14.ru/api.php?action=query&meta=siteinfo&siprop=general&format=json' | |||
).then(function(response) { | |||
return response.json(); | |||
}).then(function(data) { | |||
return getUnixTime(data.query.general.time); | |||
}); | |||
} | } | ||
function updateServerInfo(serverObj, serverName) { | function updateServerInfo(serverObj, serverName) { | ||
var serverStatusFrame = document.getElementById(serverName); | |||
var statusText = { | |||
0: "Лобби", | |||
1: "Раунд идёт", | |||
2: "Завершение" | |||
}; | |||
serverStatusFrame.querySelector(".serverInfoRoundSet").textContent = "#" + | |||
serverObj.round; | |||
serverStatusFrame.querySelector(".serverStatusSet").textContent = statusText[ | |||
serverObj.status] || "Неизвестный статус"; | |||
serverStatusFrame.querySelector(".serverMapSet").textContent = serverObj.map; | |||
serverStatusFrame.querySelector(".serverTimeSet").textContent = serverObj.time; | |||
serverStatusFrame.querySelector(".serverPlayersSet").textContent = serverObj.players; | |||
serverStatusFrame.querySelector(".serverPresetSet").textContent = serverObj.preset; | |||
// Получаем строку подключения из serversStatus | |||
const serverData = serversStatus.find(function(server) { | |||
return server.name === serverName; | |||
}); | |||
var connectionStringElement = serverStatusFrame.querySelector( | |||
".serverConnectSet"); | |||
if (connectionStringElement) { | |||
connectionStringElement.textContent = serverData ? serverData.serverconnect : | |||
'-'; // Устанавливаем строку подключения | |||
} | |||
// Обновляем прогресс-бар | |||
var progressBar = serverStatusFrame.querySelector(".progressBar"); // Предполагаем, что у вас есть элемент для прогресс-бара | |||
if (progressBar) { | |||
progressBar.style.width = serverObj.percentage + '%'; // Устанавливаем ширину прогресс-бара | |||
} | |||
// Обновляем отображение процента | |||
var percentageDisplay = serverStatusFrame.querySelector(".percentageDisplay"); // Элемент для отображения процента | |||
if (percentageDisplay) { | |||
percentageDisplay.textContent = serverObj.percentage + '%'; // Устанавливаем текст с процентом | |||
} | |||
} | } | ||
function updateAllServersInfo() { | function updateAllServersInfo() { | ||
serversStatus.forEach(function(server) { | |||
updateServerInfoByConnect(server.connect, server.name); | |||
}); | |||
} | } | ||
function copyToClipboard(connectUrl) { | function copyToClipboard(connectUrl) { | ||
const copyIcons = document.querySelectorAll('.copy-icon'); | |||
copyIcons.forEach(function(icon) { | |||
icon.addEventListener('click', function() { | |||
// Находим предыдущий элемент | |||
const previousElement = this.previousElementSibling; | |||
if (previousElement) { | |||
// Получаем текстовое содержимое | |||
const textToCopy = previousElement.textContent; | |||
const tempInput = document.createElement('input'); | |||
tempInput.value = textToCopy; | |||
document.body.appendChild(tempInput); | |||
tempInput.select(); | |||
document.execCommand('copy'); | |||
document.body.removeChild(tempInput); | |||
// Визуальный эффект | |||
this.style.opacity = '0.5'; // Сменяем прозрачность | |||
setTimeout(function() { | |||
this.style.opacity = '1'; // Возвращаем прозрачность | |||
}.bind(this), 200); // Через 1 секунду | |||
} | |||
}); | |||
}); | |||
} | } | ||
function customCSS(textCSS) { | function customCSS(textCSS) { | ||
const styleSheet = document.createElement("style"); | |||
styleSheet.textContent = textCSS; | |||
//console.log(textCSS); | |||
document.head.appendChild(styleSheet); | |||
} | } | ||
function createIframe(id) { | function createIframe(id) { | ||
const config = IFRAME_CONFIG[id]; | |||
if (!config) return; | |||
const iframe = document.createElement('iframe'); | |||
if (config.src && config.src !== "") { | |||
iframe.src = config.src; | |||
} | |||
if (config.srcdoc && config.srcdoc !== "") { | |||
iframe.srcdoc = config.srcdoc; | |||
} | |||
if (config.width && config.width !== "") { | |||
iframe.width = config.width; | |||
} else { | |||
iframe.width = '100%'; // Значение по умолчанию | |||
} | |||
if (config.height && config.height !== "") { | |||
iframe.height = config.height; | |||
} else { | |||
iframe.height = '400px'; // Значение по умолчанию | |||
} | |||
if (config.name && config.name !== "") { | |||
iframe.name = config.name; | |||
} | |||
if (config.allow && config.allow !== "") { | |||
iframe.allow = config.allow; | |||
} | |||
if (config.referrerpolicy && config.referrerpolicy !== "") { | |||
iframe.referrerPolicy = config.referrerpolicy; | |||
} | |||
if (config.sandbox && config.sandbox !== "") { | |||
iframe.sandbox = config.sandbox; | |||
} | |||
iframe.id = config.id || ''; // id может быть пустым, если не задано | |||
return iframe; | |||
} | } | ||
$(document).ready(function() { | $(document).ready(function() { | ||
var serversStatus = document.querySelectorAll('.serversStatus'); | |||
if (serversStatus.length > 0) { | |||
updateAllServersInfo(); | |||
// Перезапускать каждую минуту (60000 мс) | |||
setInterval(updateAllServersInfo, 60000); | |||
} | |||
var cssEls = document.querySelectorAll('.customCSS'); | |||
if (cssEls.length > 0) { | |||
for (var j = 0; j < cssEls.length; j++) { | |||
const textCSS = cssEls[j].textContent; | |||
//console.log(textCSS); | |||
customCSS(textCSS); | |||
} | |||
} | |||
const copyServerConnectionIcon = document.querySelectorAll( | |||
'.copyServerConnectionIcon'); | |||
copyServerConnectionIcon.forEach(function(icon) { | |||
icon.addEventListener('click', function() { | |||
const connectUrl = this.getAttribute('data-connect'); | |||
copyToClipboard(connectUrl); | |||
}); | |||
}); | |||
copyToClipboard(); | |||
var divs = document.querySelectorAll('.customIFrame'); | |||
if (divs) { | |||
for (var i = 0; i < divs.length; i++) { | |||
var div = divs[i]; | |||
var id = div.id; | |||
var iframe = createIframe(id); | |||
if (iframe) { | |||
div.appendChild(iframe); | |||
} | |||
} | |||
} | |||
}); | }); | ||
/*WikiEditor/Викификатор*/ | /*WikiEditor/Викификатор*/ | ||
if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) !== -1) { | if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) !== -1) { | ||
mw.loader.load( | |||
'//ru.wikipedia.org/w/index.php?title=MediaWiki:Gadget-wikificator.js&action=raw&ctype=text/javascript' | |||
); | |||
} | } | ||
var customizeToolbar = function() { | var customizeToolbar = function() { | ||
$('#wpTextbox1').wikiEditor('addToToolbar', { | |||
'section': 'advanced', | |||
'group': 'format', | |||
'tools': { | |||
'wikify': { | |||
label: 'Викификатор', | |||
type: 'button', | |||
icon: '//upload.wikimedia.org/wikipedia/commons/0/06/Wikify-toolbutton.png', | |||
action: { | |||
type: 'callback', | |||
execute: function(context) { | |||
Wikify(); | |||
} | |||
} | |||
} | |||
} | |||
}); | |||
}; | }; | ||
if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) !== -1) { | if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) !== -1) { | ||
mw.loader.using('user.options', function() { | |||
if (mw.user.options.get('usebetatoolbar')) { | |||
mw.loader.using('ext.wikiEditor.toolbar', function() { | |||
$(document).ready(customizeToolbar); | |||
}); | |||
} | |||
}); | |||
} | } | ||
/** | /** | ||
| Строка 360: | Строка 343: | ||
/* Variables for interface text used throughout the script, for ease of translating */ | /* Variables for interface text used throughout the script, for ease of translating */ | ||
var i18n = { | var i18n = { | ||
// Collapsible elements and page loader | |||
hideText: 'скрыть', | |||
showText: 'показать', | |||
// Page loader | |||
loadErrorTitle: 'Возникла ошибка при загрузке содержимого' | |||
}; | }; | ||
var mcw = window.mcw = {}; | var mcw = window.mcw = {}; | ||
| Строка 371: | Строка 354: | ||
/* Fired whenever wiki content is added. (#mw-content-text, live preview, load page, etc.) */ | /* Fired whenever wiki content is added. (#mw-content-text, live preview, load page, etc.) */ | ||
mw.hook('wikipage.content').add(function($wikipageContent) { | mw.hook('wikipage.content').add(function($wikipageContent) { | ||
/** | |||
* Page loader | |||
* | |||
* Allows a page to be downloaded and displayed on demand. | |||
* Use with Template:LoadPage and Template:LoadBox | |||
*/ | |||
(function() { | |||
var $loadPage = $wikipageContent.find('.load-page'); | |||
if (!$loadPage.length) { | |||
return; | |||
} | |||
// We need the spinner to show loading is happening, but we don't want | |||
// to have a delay while the module downloads, so we'll load this now, | |||
// regardless of if something is clicked | |||
mw.loader.load('jquery.spinner'); | |||
// Create button starting with hide text | |||
// Will be changed to the show text while calculating the maximum button size | |||
var $buttonTemplate = $('<span>').addClass( | |||
'mw-editsection-like load-page-button').append('[ ', $('<span>').addClass( | |||
'jslink').text(i18n.hideText), ' ]'); | |||
var extractList = function($contentContainer, listClass) { | |||
var $content = $contentContainer.find('.mw-parser-output > ul > li > ul') | |||
.children(':not(.nbttree-inherited)'); | |||
if (listClass) { | |||
$content.addClass(listClass); | |||
} | |||
return $content; | |||
}; | |||
$loadPage.each(function() { | |||
var $body = $(this); | |||
var page = $body.data('page'); | |||
if (!page) { | |||
return; | |||
} | |||
var template = $body.data('template'); | |||
var treeview = $body.data('treeview'); | |||
var treeviewClass = $body.data('treeviewclass'); | |||
var $heading; | |||
var $contentContainer; | |||
var $content; | |||
var $button = $buttonTemplate.clone(); | |||
var $buttonLink = $button.find('.jslink'); | |||
if (treeview) { | |||
$heading = $body; | |||
$contentContainer = $('<div>'); | |||
} else { | |||
$heading = $body.children().first(); | |||
$contentContainer = $body.find('.load-page-content'); | |||
} | |||
// Add the button | |||
$heading.append($button); | |||
// Move the edit button to the right spot | |||
$contentContainer.find('.mw-editsection, .mw-editsection-like').insertAfter( | |||
$button); | |||
// Find max button width, and set its min-width to it | |||
var hideWidth = $button.width(); | |||
$buttonLink.text(i18n.showText); | |||
var showWidth = $button.width(); | |||
if (hideWidth !== showWidth) { | |||
$button.css('min-width', hideWidth > showWidth ? hideWidth : showWidth); | |||
} | |||
$buttonLink.click(function() { | |||
if ($body.hasClass('pageloader-contentloaded')) { | |||
if ($buttonLink.text() === i18n.showText) { | |||
if (treeview) { | |||
$content.insertAfter($body); | |||
} else { | |||
$contentContainer.show(); | |||
} | |||
$buttonLink.text(i18n.hideText); | |||
} else { | |||
if (treeview) { | |||
$content.detach(); | |||
} else { | |||
$contentContainer.hide(); | |||
} | |||
$buttonLink.text(i18n.showText); | |||
} | |||
return; | |||
} | |||
// See if this was loaded elsewhere before making a request | |||
var gotContent; | |||
$('.pageloader-contentloaded').each(function() { | |||
var $fLoader = $(this); | |||
if ($fLoader.data('page') === page && $fLoader.data( | |||
'pageloader-content')) { | |||
$contentContainer.html($fLoader.data('pageloader-content')).removeClass( | |||
'noscript'); | |||
mw.hook('wikipage.content').fire($contentContainer); | |||
if (treeview) { | |||
$body.find('.noscript').remove(); | |||
$content = extractList($contentContainer, treeviewClass); | |||
$content.insertAfter($body); | |||
} | |||
$buttonLink.text(i18n.hideText); | |||
$body.addClass('pageloader-contentloaded'); | |||
gotContent = true; | |||
return false; | |||
} | |||
}); | |||
if (gotContent) { | |||
return; | |||
} | |||
// Just in-case the spinner module is still not ready yet | |||
var $spinner = $(); | |||
mw.loader.using('jquery.spinner', function() { | |||
// $spinner will be false if the content somehow loaded before the module did | |||
if ($spinner) { | |||
$spinner = $.createSpinner().addClass('mw-editsection-like').css( | |||
'min-width', $button.css('min-width')); | |||
$button.hide().after($spinner); | |||
} | |||
}); | |||
var requestData = { | |||
action: 'parse', | |||
prop: 'text' | |||
}; | |||
if (template) { | |||
requestData.page = page; | |||
} else { | |||
requestData.title = mw.config.get('wgPageName'); | |||
requestData.text = '{' + '{:' + page + '}}'; | |||
} | |||
new mw.Api().get(requestData).done(function(data) { | |||
var html = data.parse.text['*']; | |||
$contentContainer.html(html).removeClass('noscript'); | |||
// Resolve self-links | |||
if (template) { | |||
var curPage = '/' + mw.config.get('wgPageName'); | |||
$contentContainer.find('a').each(function() { | |||
var $link = $(this); | |||
if ($link.attr('href') === curPage) { | |||
$link.replaceWith($('<strong>').addClass('selflink').append( | |||
$link.contents())); | |||
} | |||
}); | |||
html = $contentContainer.html(); | |||
} | |||
$body.data('pageloader-content', html); | |||
// Fire content hook on the new content, running all this stuff again and more :) | |||
mw.hook('wikipage.content').fire($contentContainer); | |||
if (treeview) { | |||
$body.find('.noscript').remove(); | |||
$content = extractList($contentContainer, treeviewClass); | |||
$content.insertAfter($body); | |||
} | |||
$spinner.remove(); | |||
$spinner = false; | |||
$buttonLink.text(i18n.hideText); | |||
$button.show(); | |||
$body.addClass('pageloader-contentloaded'); | |||
}).fail(function(_, error) { | |||
$spinner.remove(); | |||
$spinner = false; | |||
$button.show(); | |||
var errorText = ''; | |||
if (error.textStatus) { | |||
errorText = error.textStatus; | |||
} else if (error.error) { | |||
errorText = error.error.info; | |||
} | |||
mw.notify(errorText, { | |||
title: i18n.loadErrorTitle, | |||
autoHide: false | |||
}); | |||
}); | |||
}); | |||
}); | |||
}()); | |||
/** | |||
* Element animator | |||
* | |||
* Will cycle the active class on any child elements | |||
* within an element with the animated class. | |||
*/ | |||
(function() { | |||
if (!mcw.animate) { | |||
mcw.animate = setInterval(function() { | |||
$('.animated').each(function() { | |||
var $elem = $(this); | |||
var $current = $elem.children('.active'); | |||
var $next = $current.nextAll(':not(.skip):first'); | |||
// Loop back to the start | |||
if (!$next.length) { | |||
$next = $elem.children(':not(.skip):first'); | |||
} | |||
$current.removeClass('active'); | |||
$next.addClass('active'); | |||
}); | |||
}, 2000); | |||
} | |||
}()); | |||
}); | }); | ||
// SS220 import end | // SS220 import end | ||
Версия от 00:07, 23 августа 2024
const IFRAME_CONFIG = {
iframe1: {
src: 'https://example.com',
srcdoc: '',
width: '600',
height: '400',
name: 'iframe1',
allow: 'clipboard-write',
referrerpolicy: 'no-referrer',
sandbox: 'allow-same-origin',
id: 'iframe1'
},
iframe2: {
src: '',
srcdoc: '<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Bootstrap demo</title><link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"><script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script></head><body><form><div class="mb-3"><label for="exampleInputEmail1" class="form-label">Email address</label><input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp"><div id="emailHelp" class="form-text">We ll never share your email with anyone else.</div></div><div class="mb-3"><label for="exampleInputPassword1" class="form-label">Password</label><input type="password" class="form-control" id="exampleInputPassword1"></div><div class="mb-3 form-check"><input type="checkbox" class="form-check-input" id="exampleCheck1"><label class="form-check-label" for="exampleCheck1">Check me out</label></div><button type="submit" class="btn btn-primary">Submit</button></form></body></html>',
width: '600',
height: '400',
name: 'iframe2',
allow: '',
referrerpolicy: '',
sandbox: '',
id: 'iframe2'
}
};
const currentURL = window.location.href;
const serversStatus = [{
name: "server-main",
connect: "https://game2.station14.ru/main/server/status",
serverconnect: "game2.station14.ru/main/server"
}, {
name: "server-nova",
connect: "https://game2.station14.ru/nova/server/status",
serverconnect: "game2.station14.ru/nova/server"
}, {
name: "server-athara",
connect: "https://game2.station14.ru/athara/server/status",
serverconnect: "game2.station14.ru/athara/server"
}, {
name: "server-solaris",
connect: "https://game2.station14.ru/solaris/server/status",
serverconnect: "game2.station14.ru/solaris/server"
}, {
name: "server-echo",
connect: "https://game2.station14.ru/echo/server/status",
serverconnect: "game2.station14.ru/echo/server"
}, {
name: "server-elysium",
connect: "https://game2.station14.ru/elysium/server/status",
serverconnect: "game2.station14.ru/elysium/server"
}, {
name: "server-nebula",
connect: "https://game2.station14.ru/nebula/server/status",
serverconnect: "game2.station14.ru/nebula/server"
}, {
name: "server-wl",
connect: "https://game2.station14.ru/wl/server/status",
serverconnect: "game2.station14.ru/wl/server"
}, {
name: "server-frontier",
connect: "https://api.codetabs.com/v1/proxy/?quest=https://arles.station14.ru/frontier-main/server/status",
serverconnect: "arles.station14.ru/frontier-main/server"
}, {
name: "server-fallout",
connect: "https://api.codetabs.com/v1/proxy/?quest=http://188.92.78.98:1221/status",
serverconnect: "188.92.78.98:1221"
}, {
name: "server-marines",
connect: "https://game1.station14.ru/marines-main/server/status",
serverconnect: "game1.station14.ru/marines-main/server"
}, {
name: "server-stalker",
connect: "https://api.codetabs.com/v1/proxy/?quest=https://game.stalkers14.xyz/status",
serverconnect: "game.stalkers14.xyz"
}];
function getXHRInfo(url) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = function() {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.responseText));
} else {
reject('Ошибка при выполнении запроса: ' + xhr.status);
}
};
xhr.onerror = function() {
reject('Ошибка при выполнении запроса');
};
xhr.send();
});
}
function updateServerInfoByConnect(connect, name) {
getServerTime().then(function(currentUnixTime) {
return getXHRInfo(connect).then(function(serverData) {
var unixStartRound = getUnixTime(serverData.round_start_time);
var timeDisplay = unixStartRound ? secondsToDHM(currentUnixTime -
unixStartRound) : "–";
var currentPlayers = serverData.players;
var maxPlayers = serverData.soft_max_players;
// Вычисляем процент
var percentage = maxPlayers > 0 ? Math.round((currentPlayers /
maxPlayers) * 100) : 0;
// Форматируем строку с количеством игроков
var playersDisplay = currentPlayers && maxPlayers ? currentPlayers + '/' +
maxPlayers : "–";
// Функция для проверки на пустые данные
function checkValue(value) {
return value ? value : "–";
}
var serverInfo = {
name: checkValue(serverData.name),
round: checkValue(serverData.round_id),
status: checkValue(serverData.run_level),
map: checkValue(serverData.map),
time: timeDisplay,
players: playersDisplay,
preset: checkValue(serverData.preset),
percentage: percentage
};
updateServerInfo(serverInfo, name);
//console.log("serverInfo", serverInfo, "currentUnixTime", currentUnixTime,"unixStartRound", unixStartRound);
});
}).catch(function(error) {
console.error(error);
});
}
function getUnixTime(dateString) {
return Math.floor(new Date(dateString).getTime() / 1000); // Делим на 1000, чтобы получить секунды
}
function secondsToDHM(seconds) {
var days = Math.floor(seconds / 86400);
var hours = Math.floor((seconds % 86400) / 3600);
var minutes = Math.floor((seconds % 3600) / 60);
var result = "";
if (days > 0) result += days + " дн, ";
if (hours > 0) result += hours + " ч ";
// Проверка на наличие минут
if (minutes > 0) {
result += minutes + " мин";
} else {
result += "–"; // Символ ожидания, если минут нет
}
return result.trim();
}
function getServerTime() {
return fetch(
'https://station14.ru/api.php?action=query&meta=siteinfo&siprop=general&format=json'
).then(function(response) {
return response.json();
}).then(function(data) {
return getUnixTime(data.query.general.time);
});
}
function updateServerInfo(serverObj, serverName) {
var serverStatusFrame = document.getElementById(serverName);
var statusText = {
0: "Лобби",
1: "Раунд идёт",
2: "Завершение"
};
serverStatusFrame.querySelector(".serverInfoRoundSet").textContent = "#" +
serverObj.round;
serverStatusFrame.querySelector(".serverStatusSet").textContent = statusText[
serverObj.status] || "Неизвестный статус";
serverStatusFrame.querySelector(".serverMapSet").textContent = serverObj.map;
serverStatusFrame.querySelector(".serverTimeSet").textContent = serverObj.time;
serverStatusFrame.querySelector(".serverPlayersSet").textContent = serverObj.players;
serverStatusFrame.querySelector(".serverPresetSet").textContent = serverObj.preset;
// Получаем строку подключения из serversStatus
const serverData = serversStatus.find(function(server) {
return server.name === serverName;
});
var connectionStringElement = serverStatusFrame.querySelector(
".serverConnectSet");
if (connectionStringElement) {
connectionStringElement.textContent = serverData ? serverData.serverconnect :
'-'; // Устанавливаем строку подключения
}
// Обновляем прогресс-бар
var progressBar = serverStatusFrame.querySelector(".progressBar"); // Предполагаем, что у вас есть элемент для прогресс-бара
if (progressBar) {
progressBar.style.width = serverObj.percentage + '%'; // Устанавливаем ширину прогресс-бара
}
// Обновляем отображение процента
var percentageDisplay = serverStatusFrame.querySelector(".percentageDisplay"); // Элемент для отображения процента
if (percentageDisplay) {
percentageDisplay.textContent = serverObj.percentage + '%'; // Устанавливаем текст с процентом
}
}
function updateAllServersInfo() {
serversStatus.forEach(function(server) {
updateServerInfoByConnect(server.connect, server.name);
});
}
function copyToClipboard(connectUrl) {
const copyIcons = document.querySelectorAll('.copy-icon');
copyIcons.forEach(function(icon) {
icon.addEventListener('click', function() {
// Находим предыдущий элемент
const previousElement = this.previousElementSibling;
if (previousElement) {
// Получаем текстовое содержимое
const textToCopy = previousElement.textContent;
const tempInput = document.createElement('input');
tempInput.value = textToCopy;
document.body.appendChild(tempInput);
tempInput.select();
document.execCommand('copy');
document.body.removeChild(tempInput);
// Визуальный эффект
this.style.opacity = '0.5'; // Сменяем прозрачность
setTimeout(function() {
this.style.opacity = '1'; // Возвращаем прозрачность
}.bind(this), 200); // Через 1 секунду
}
});
});
}
function customCSS(textCSS) {
const styleSheet = document.createElement("style");
styleSheet.textContent = textCSS;
//console.log(textCSS);
document.head.appendChild(styleSheet);
}
function createIframe(id) {
const config = IFRAME_CONFIG[id];
if (!config) return;
const iframe = document.createElement('iframe');
if (config.src && config.src !== "") {
iframe.src = config.src;
}
if (config.srcdoc && config.srcdoc !== "") {
iframe.srcdoc = config.srcdoc;
}
if (config.width && config.width !== "") {
iframe.width = config.width;
} else {
iframe.width = '100%'; // Значение по умолчанию
}
if (config.height && config.height !== "") {
iframe.height = config.height;
} else {
iframe.height = '400px'; // Значение по умолчанию
}
if (config.name && config.name !== "") {
iframe.name = config.name;
}
if (config.allow && config.allow !== "") {
iframe.allow = config.allow;
}
if (config.referrerpolicy && config.referrerpolicy !== "") {
iframe.referrerPolicy = config.referrerpolicy;
}
if (config.sandbox && config.sandbox !== "") {
iframe.sandbox = config.sandbox;
}
iframe.id = config.id || ''; // id может быть пустым, если не задано
return iframe;
}
$(document).ready(function() {
var serversStatus = document.querySelectorAll('.serversStatus');
if (serversStatus.length > 0) {
updateAllServersInfo();
// Перезапускать каждую минуту (60000 мс)
setInterval(updateAllServersInfo, 60000);
}
var cssEls = document.querySelectorAll('.customCSS');
if (cssEls.length > 0) {
for (var j = 0; j < cssEls.length; j++) {
const textCSS = cssEls[j].textContent;
//console.log(textCSS);
customCSS(textCSS);
}
}
const copyServerConnectionIcon = document.querySelectorAll(
'.copyServerConnectionIcon');
copyServerConnectionIcon.forEach(function(icon) {
icon.addEventListener('click', function() {
const connectUrl = this.getAttribute('data-connect');
copyToClipboard(connectUrl);
});
});
copyToClipboard();
var divs = document.querySelectorAll('.customIFrame');
if (divs) {
for (var i = 0; i < divs.length; i++) {
var div = divs[i];
var id = div.id;
var iframe = createIframe(id);
if (iframe) {
div.appendChild(iframe);
}
}
}
});
/*WikiEditor/Викификатор*/
if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) !== -1) {
mw.loader.load(
'//ru.wikipedia.org/w/index.php?title=MediaWiki:Gadget-wikificator.js&action=raw&ctype=text/javascript'
);
}
var customizeToolbar = function() {
$('#wpTextbox1').wikiEditor('addToToolbar', {
'section': 'advanced',
'group': 'format',
'tools': {
'wikify': {
label: 'Викификатор',
type: 'button',
icon: '//upload.wikimedia.org/wikipedia/commons/0/06/Wikify-toolbutton.png',
action: {
type: 'callback',
execute: function(context) {
Wikify();
}
}
}
}
});
};
if ($.inArray(mw.config.get('wgAction'), ['edit', 'submit']) !== -1) {
mw.loader.using('user.options', function() {
if (mw.user.options.get('usebetatoolbar')) {
mw.loader.using('ext.wikiEditor.toolbar', function() {
$(document).ready(customizeToolbar);
});
}
});
}
/**
* Taken from https://wiki.ss220.space/index.php?title=MediaWiki:Common.js&oldid=35626
*/
/* Variables for interface text used throughout the script, for ease of translating */
var i18n = {
// Collapsible elements and page loader
hideText: 'скрыть',
showText: 'показать',
// Page loader
loadErrorTitle: 'Возникла ошибка при загрузке содержимого'
};
var mcw = window.mcw = {};
/* Keep track of delegated events on dynamic content */
mcw.events = {};
/* Fired whenever wiki content is added. (#mw-content-text, live preview, load page, etc.) */
mw.hook('wikipage.content').add(function($wikipageContent) {
/**
* Page loader
*
* Allows a page to be downloaded and displayed on demand.
* Use with Template:LoadPage and Template:LoadBox
*/
(function() {
var $loadPage = $wikipageContent.find('.load-page');
if (!$loadPage.length) {
return;
}
// We need the spinner to show loading is happening, but we don't want
// to have a delay while the module downloads, so we'll load this now,
// regardless of if something is clicked
mw.loader.load('jquery.spinner');
// Create button starting with hide text
// Will be changed to the show text while calculating the maximum button size
var $buttonTemplate = $('<span>').addClass(
'mw-editsection-like load-page-button').append('[ ', $('<span>').addClass(
'jslink').text(i18n.hideText), ' ]');
var extractList = function($contentContainer, listClass) {
var $content = $contentContainer.find('.mw-parser-output > ul > li > ul')
.children(':not(.nbttree-inherited)');
if (listClass) {
$content.addClass(listClass);
}
return $content;
};
$loadPage.each(function() {
var $body = $(this);
var page = $body.data('page');
if (!page) {
return;
}
var template = $body.data('template');
var treeview = $body.data('treeview');
var treeviewClass = $body.data('treeviewclass');
var $heading;
var $contentContainer;
var $content;
var $button = $buttonTemplate.clone();
var $buttonLink = $button.find('.jslink');
if (treeview) {
$heading = $body;
$contentContainer = $('<div>');
} else {
$heading = $body.children().first();
$contentContainer = $body.find('.load-page-content');
}
// Add the button
$heading.append($button);
// Move the edit button to the right spot
$contentContainer.find('.mw-editsection, .mw-editsection-like').insertAfter(
$button);
// Find max button width, and set its min-width to it
var hideWidth = $button.width();
$buttonLink.text(i18n.showText);
var showWidth = $button.width();
if (hideWidth !== showWidth) {
$button.css('min-width', hideWidth > showWidth ? hideWidth : showWidth);
}
$buttonLink.click(function() {
if ($body.hasClass('pageloader-contentloaded')) {
if ($buttonLink.text() === i18n.showText) {
if (treeview) {
$content.insertAfter($body);
} else {
$contentContainer.show();
}
$buttonLink.text(i18n.hideText);
} else {
if (treeview) {
$content.detach();
} else {
$contentContainer.hide();
}
$buttonLink.text(i18n.showText);
}
return;
}
// See if this was loaded elsewhere before making a request
var gotContent;
$('.pageloader-contentloaded').each(function() {
var $fLoader = $(this);
if ($fLoader.data('page') === page && $fLoader.data(
'pageloader-content')) {
$contentContainer.html($fLoader.data('pageloader-content')).removeClass(
'noscript');
mw.hook('wikipage.content').fire($contentContainer);
if (treeview) {
$body.find('.noscript').remove();
$content = extractList($contentContainer, treeviewClass);
$content.insertAfter($body);
}
$buttonLink.text(i18n.hideText);
$body.addClass('pageloader-contentloaded');
gotContent = true;
return false;
}
});
if (gotContent) {
return;
}
// Just in-case the spinner module is still not ready yet
var $spinner = $();
mw.loader.using('jquery.spinner', function() {
// $spinner will be false if the content somehow loaded before the module did
if ($spinner) {
$spinner = $.createSpinner().addClass('mw-editsection-like').css(
'min-width', $button.css('min-width'));
$button.hide().after($spinner);
}
});
var requestData = {
action: 'parse',
prop: 'text'
};
if (template) {
requestData.page = page;
} else {
requestData.title = mw.config.get('wgPageName');
requestData.text = '{' + '{:' + page + '}}';
}
new mw.Api().get(requestData).done(function(data) {
var html = data.parse.text['*'];
$contentContainer.html(html).removeClass('noscript');
// Resolve self-links
if (template) {
var curPage = '/' + mw.config.get('wgPageName');
$contentContainer.find('a').each(function() {
var $link = $(this);
if ($link.attr('href') === curPage) {
$link.replaceWith($('<strong>').addClass('selflink').append(
$link.contents()));
}
});
html = $contentContainer.html();
}
$body.data('pageloader-content', html);
// Fire content hook on the new content, running all this stuff again and more :)
mw.hook('wikipage.content').fire($contentContainer);
if (treeview) {
$body.find('.noscript').remove();
$content = extractList($contentContainer, treeviewClass);
$content.insertAfter($body);
}
$spinner.remove();
$spinner = false;
$buttonLink.text(i18n.hideText);
$button.show();
$body.addClass('pageloader-contentloaded');
}).fail(function(_, error) {
$spinner.remove();
$spinner = false;
$button.show();
var errorText = '';
if (error.textStatus) {
errorText = error.textStatus;
} else if (error.error) {
errorText = error.error.info;
}
mw.notify(errorText, {
title: i18n.loadErrorTitle,
autoHide: false
});
});
});
});
}());
/**
* Element animator
*
* Will cycle the active class on any child elements
* within an element with the animated class.
*/
(function() {
if (!mcw.animate) {
mcw.animate = setInterval(function() {
$('.animated').each(function() {
var $elem = $(this);
var $current = $elem.children('.active');
var $next = $current.nextAll(':not(.skip):first');
// Loop back to the start
if (!$next.length) {
$next = $elem.children(':not(.skip):first');
}
$current.removeClass('active');
$next.addClass('active');
});
}, 2000);
}
}());
});
// SS220 import end