MediaWiki:Mainpage.js:修订间差异

MediaWiki系统消息页面
(服务器状态改读雨城通v2接口;修正JSON解码错误误报下线;15秒轮询与未知状态提示(需雨城通接口CORS配套部署))
(首页服务器状态改用已实测支持跨域的基岩版API;mcstatus主源与mcsrvstat备用;保留未知状态、缓存时间与失败保护;无需修改雨城通)
 
第1行: 第1行:
$(function () {
$(function () {
     var apiUrl = 'https://yct.shangxiaoguan.top/api/operations/server-status';
     var sources = [
        { name: 'mcstatus.io', url: 'https://api.mcstatus.io/v2/status/bedrock/ld.cmsy.xyz:19132' },
        { name: 'mcsrvstat.us', url: 'https://api.mcsrvstat.us/bedrock/3/ld.cmsy.xyz:19132' }
    ];
     var inFlight = false;
     var inFlight = false;
     var lastKnown = null;
     var lastKnown = null;


     function showUnknown() {
     function normalize(data, source) {
         $('#online-ver').text('');
         if (!data || typeof data.online !== 'boolean') return null;
         if (lastKnown) {
        var checkedAt = source.name === 'mcstatus.io' ? data.retrieved_at
            : data.debug && data.debug.cachetime * 1000;
        if (typeof checkedAt !== 'number' || !Number.isFinite(checkedAt)
            || Date.now() - checkedAt > 10 * 60 * 1000 || checkedAt > Date.now() + 120000) return null;
        return {
            online: data.online,
            players: data.players,
            version: source.name === 'mcstatus.io' ? data.version && data.version.name : data.version,
            checkedAt: checkedAt,
            source: source.name
        };
    }
 
    function show(result) {
        inFlight = false;
         if (!result) {
             $('#online-player').text('状态未知');
             $('#online-player').text('状态未知');
             $('#online-desc').text('本次查询失败;上次确认' + lastKnown + '。正在重试。');
            $('#online-ver').text('');
             $('#online-desc').text('暂时无法查询服务器状态,稍后自动重试。'
                + (lastKnown ? '上次确认:' + lastKnown + '。' : ''));
            return;
        }
        var time = new Date(result.checkedAt).toLocaleTimeString('zh-CN', { hour12: false });
        var origin = '来源 ' + result.source + ',检测时间 ' + time + '(结果有缓存)。';
        if (result.online) {
            var players = result.players || {};
            var online = Number.isInteger(players.online) && players.online >= 0;
            var max = Number.isInteger(players.max) && players.max >= 0;
            $('#online-player').text(online ? players.online + (max ? '/' + players.max : ' 人在线') : '服务器在线');
            $('#online-ver').text(typeof result.version === 'string' ? 'Ver ' + result.version : '');
            $('#online-desc').text('服务器在线。' + origin);
            lastKnown = '在线(' + time + ')';
         } else {
         } else {
             $('#online-player').text('状态未知');
             $('#online-player').text('未响应');
             $('#online-desc').text('暂时无法查询服务器状态,稍后自动重试。');
            $('#online-ver').text('');
             $('#online-desc').text('第三方检测未收到服务器响应,请稍后重试。' + origin);
            lastKnown = '未响应(' + time + ')';
         }
         }
     }
     }


     function getServerStatus() {
     function query(index, candidate) {
         if (inFlight || document.hidden) return;
         if (index >= sources.length) {
         inFlight = true;
            show(candidate);
         $.ajax({ url: apiUrl, dataType: 'json', cache: false, timeout: 12000 })
            return;
         }
        var source = sources[index];
         $.ajax({ url: source.url, dataType: 'json', timeout: 10000 })
             .done(function (data) {
             .done(function (data) {
                 var item = data && data.item;
                 var result = normalize(data, source);
                 if (!item || (item.availability !== 'online' && item.availability !== 'offline')) {
                 if (result && result.online) {
                    showUnknown();
                     show(result);
                    return;
                }
                var checked = new Date(item.checkedAt);
                if (!Number.isFinite(checked.getTime()) || Math.abs(Date.now() - checked.getTime()) > 120000) {
                    showUnknown();
                    return;
                }
                var time = checked.toLocaleTimeString('zh-CN', { hour12: false });
                $('#online-ver').text('');
                if (item.availability === 'online') {
                     var count = item.onlinePlayerCount;
                    $('#online-player').text(Number.isInteger(count) && count >= 0 ? count + ' 人在线' : '服务器在线');
                    var latency = typeof item.latencyMs === 'number' && Number.isFinite(item.latencyMs) && item.latencyMs >= 0
                        ? ',查询延迟 ' + Math.round(item.latencyMs) + ' 毫秒' : '';
                    $('#online-desc').text('服务器在线' + latency + '。核对时间 ' + time + '。');
                    lastKnown = '在线(' + time + ')';
                 } else {
                 } else {
                     $('#online-player').text('服务暂不可用');
                     var latest = result && (!candidate || result.checkedAt > candidate.checkedAt) ? result : candidate;
                     $('#online-desc').text('雨城通暂时无法连接服务器数据源。核对时间 ' + time + '。');
                     query(index + 1, latest);
                    lastKnown = '数据源暂不可用(' + time + ')';
                 }
                 }
             })
             })
             .fail(showUnknown)
             .fail(function () { query(index + 1, candidate); });
            .always(function () { inFlight = false; });
    }
 
    function getServerStatus() {
        if (inFlight || document.hidden) return;
        inFlight = true;
        query(0, null);
     }
     }


     getServerStatus();
     getServerStatus();
     window.setInterval(getServerStatus, 15000);
     window.setInterval(getServerStatus, 60000);
     document.addEventListener('visibilitychange', function () {
     document.addEventListener('visibilitychange', function () {
         if (!document.hidden) getServerStatus();
         if (!document.hidden) getServerStatus();
     });
     });
});
});

2026年10月29日 (四) 10:29的最新版本

$(function () {
    var sources = [
        { name: 'mcstatus.io', url: 'https://api.mcstatus.io/v2/status/bedrock/ld.cmsy.xyz:19132' },
        { name: 'mcsrvstat.us', url: 'https://api.mcsrvstat.us/bedrock/3/ld.cmsy.xyz:19132' }
    ];
    var inFlight = false;
    var lastKnown = null;

    function normalize(data, source) {
        if (!data || typeof data.online !== 'boolean') return null;
        var checkedAt = source.name === 'mcstatus.io' ? data.retrieved_at
            : data.debug && data.debug.cachetime * 1000;
        if (typeof checkedAt !== 'number' || !Number.isFinite(checkedAt)
            || Date.now() - checkedAt > 10 * 60 * 1000 || checkedAt > Date.now() + 120000) return null;
        return {
            online: data.online,
            players: data.players,
            version: source.name === 'mcstatus.io' ? data.version && data.version.name : data.version,
            checkedAt: checkedAt,
            source: source.name
        };
    }

    function show(result) {
        inFlight = false;
        if (!result) {
            $('#online-player').text('状态未知');
            $('#online-ver').text('');
            $('#online-desc').text('暂时无法查询服务器状态,稍后自动重试。'
                + (lastKnown ? '上次确认:' + lastKnown + '。' : ''));
            return;
        }
        var time = new Date(result.checkedAt).toLocaleTimeString('zh-CN', { hour12: false });
        var origin = '来源 ' + result.source + ',检测时间 ' + time + '(结果有缓存)。';
        if (result.online) {
            var players = result.players || {};
            var online = Number.isInteger(players.online) && players.online >= 0;
            var max = Number.isInteger(players.max) && players.max >= 0;
            $('#online-player').text(online ? players.online + (max ? '/' + players.max : ' 人在线') : '服务器在线');
            $('#online-ver').text(typeof result.version === 'string' ? 'Ver ' + result.version : '');
            $('#online-desc').text('服务器在线。' + origin);
            lastKnown = '在线(' + time + ')';
        } else {
            $('#online-player').text('未响应');
            $('#online-ver').text('');
            $('#online-desc').text('第三方检测未收到服务器响应,请稍后重试。' + origin);
            lastKnown = '未响应(' + time + ')';
        }
    }

    function query(index, candidate) {
        if (index >= sources.length) {
            show(candidate);
            return;
        }
        var source = sources[index];
        $.ajax({ url: source.url, dataType: 'json', timeout: 10000 })
            .done(function (data) {
                var result = normalize(data, source);
                if (result && result.online) {
                    show(result);
                } else {
                    var latest = result && (!candidate || result.checkedAt > candidate.checkedAt) ? result : candidate;
                    query(index + 1, latest);
                }
            })
            .fail(function () { query(index + 1, candidate); });
    }

    function getServerStatus() {
        if (inFlight || document.hidden) return;
        inFlight = true;
        query(0, null);
    }

    getServerStatus();
    window.setInterval(getServerStatus, 60000);
    document.addEventListener('visibilitychange', function () {
        if (!document.hidden) getServerStatus();
    });
});