您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
哎!
// ==UserScript== // @name 小米路由器增强脚本 // @namespace https://blog.iccfish.com/ // @version 0.3.0 // @description 哎! // @author 木鱼([email protected]) // @include /http:\/\/.*?\/cgi-bin\/luci\/;stok.*/ // @grant unsafeWindow // @run-at document-start // ==/UserScript== function boot() { let pathName = location.pathname; if (/\/web\/home/.test(pathName)) { initHomePage(); } } let token, jQuery, uw = unsafeWindow; function getToken() { if (!token) token = /;stok=([\da-f]+)/.exec(location.href) && RegExp.$1; return token; } function initHomePage() { var s = document.createElement("style"); s.id = "blog.iccfish.com"; s.textContent = ".device-speed { float: right; }\ .up-speed, .down-speed { display: inline-block; padding-left: 16px; border: 1px solid #ff4c00; color: #ff4c00; position: relative; --percentage: 0; width: 110px; text-align: center; font-size: 90%; }\ .up-speed:after, .down-speed:after { content: '🔼'; position: absolute; left: 0; top: 0; line-height: 150%; }\ .up-speed:before, .down-speed:before { content: ' '; position: absolute; left: 0; top: 0; bottom: 0; background: rgba(255,0,0,0.25); width: var(--percentage); }\ .down-speed { color:#0059fa; border-color:#0059fa; }\ .down-speed:after { content: '🔽'; }\ .down-speed:before { background-color: rgb(0 68 255 / 25%); }\ "; document.head.appendChild(s); // 替换模板 let devicesItemTmpl = document.querySelector("#tmpldevicesitem"); devicesItemTmpl.innerHTML = '\ <tr class="device-item" data-mac="{$mac}">\ <td>\ <img class="dev-icon" width="60" src="{$devices_icon}" onerror="this.src=\'/img/device_list_error.png\'">\ <div class="dev-info">\ <div class="name">{$name} {if($isself)}<span class="muted">| 本机</span>{/if}</div>\ <ul class="devnetinfo clearfix">\ <li><span class="k">已连接:</span> <span class="v online-time">{$online}</span></li>\ <li>{for(var i=0, len=$ip.length; i<len; i++)}<p data-ip="{$ip[i]}"><span class="k">IP地址:</span> <span class="v">{$ip[i]}</span></p>{/for}</li>\ <li><span class="k">MAC地址:</span> <span class="v">{$mac}</span></li>\ </ul>\ </div>\ </td>\ {if($d_is_ap != 8)}<td class="option">{$option}</td>{/if}\ {if($d_is_ap == 8)}<td class="option_d01"></td>{/if}\ {if($hasDisk)}<td class="option2">{$option2}</td>{/if}\ </tr>'; // 处理数据 let lock; function showSpeed(list) { let needFullReload = false; let totalUpload = 0, totalDownload = 0; list.filter(item => item.statistics).forEach(item => { totalDownload += +item.statistics.downspeed; totalUpload += +item.statistics.upspeed; }); list.forEach(item => { if (item.statistics) { let mac = item.mac; let tr = uw.$(`tr.device-item[data-mac='${mac}']`); if (!tr) { needFullReload = true; return; } let title = tr.find("div.name"); let upspeed = uw.byteFormat(+item.statistics.upspeed, 100) + "/S"; let downspeed = uw.byteFormat(+item.statistics.downspeed, 100) + "/S"; let online = jQuery.secondToDate(+item.statistics.online); let ups = title.find(".up-speed"); const pu = totalUpload ? Math.round((+item.statistics.upspeed * 10000) / totalUpload) / 100 : 0; const pd = totalDownload ? Math.round((+item.statistics.downspeed * 10000) / totalDownload) / 100 : 0; if (ups.length) { ups.html(`${upspeed} | ${pu}%`)[0].style.setProperty("--percentage", pu + "%"); title .find(".down-speed") .html(`${downspeed} | ${pd}%`)[0] .style.setProperty("--percentage", pd + "%"); } else { let speedTmpl = `<sub class='device-speed'><span class='up-speed' style="--percentage: ${pu}%;">${upspeed} | ${pu}%</span> <span class='down-speed' style="--percentage: ${pd}%;">${downspeed} | ${pd}%</span></sub>`; title.append(speedTmpl); } tr.find(".online-time").html(online); } }); let total = jQuery("div.total-speed"); if (!total.length) { jQuery("#bd").prepend("<div class=\"total-speed\" style='padding: 10px 0;margin-bottom: -40px;font-size: 130%;color: #0a6f15;'>总速度:🔼<span style='color:#ff4c00;' class='up'>--</span> 🔽<span style='color:#0059fa;' class='down'>--</span></div>"); total = jQuery("div.total-speed"); } //debugger; total.find(".up").html(uw.byteFormat(totalUpload, 100) + "/S"); total.find(".down").html(uw.byteFormat(totalDownload, 100) + "/S"); if (location.hash !== "#devices") return; if (needFullReload) { console.log("发现新设备,需要完全重新加载."); jQuery.pub("devices:getlist"); } else { setTimeout(refreshSpeed, 1000); } } function refreshSpeed() { if (lock) return; lock = true; let api = `/cgi-bin/luci/;stok=${getToken()}/api/misystem/devicelist`; jQuery .getJSON(api, {}) .done(function (data) { if (data.code !== 0) return; showSpeed(data.list); }) .fail(function () { setTimeout(refreshSpeed, 1000); }) .always(function () { lock = false; }); } jQuery(document).ajaxComplete(function (e, xhr, setting) { if (/misystem\/devicelist/.test(setting.url)) { let data; try { data = JSON.parse(xhr.responseText); } catch (e) { console.log(`invalid reponse: ${e}.`); return; } showSpeed(data.list); } }); } (function () { let val, inited; Object.defineProperty(unsafeWindow, "jQuery", { get: function () { return val; }, set: function (v) { val = v; jQuery = v; if (!inited) { inited = true; boot(); } }, }); })();