小米路由器增强脚本

哎!

// ==UserScript==
// @name         小米路由器增强脚本
// @namespace    https://blog.iccfish.com/
// @version      0.2.2
// @description  哎!
// @author       木鱼(iccfish@qq.com)
// @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() {
	// 替换模板
	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} &nbsp;&nbsp;{if($isself)}<span class="muted">|&nbsp;本机</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.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');
				if (ups.length) {
					ups.html(upspeed);
					title.find('.down-speed').html(downspeed);
				} else {
					let speedTmpl = `<sub>↑<span style='color:red;' class='up-speed'>${upspeed}</span> ↓<span style='color:blue;' class='down-speed'>${downspeed}</span></sub>`;
					title.append(speedTmpl);
				}
				tr.find('.online-time').html(online);

				totalDownload += +item.statistics.downspeed;
				totalUpload += +item.statistics.upspeed;
			}
		});

		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:red;' class='up'>--</span> ↓<span style='color:blue;' 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();
			}
		},
	});
})();