🌴 Sync 2026-03-05 23:51:42

This commit is contained in:
github-actions[bot] committed 2026-03-05 23:51:42 +08:00
1 parent 97c049ed0a
commit 0acff03804
14253 files changed
+3893239

No files matched your search

@@ -0,0 +1,140 @@
module("luci.controller.scutclient", package.seeall)
http = require "luci.http"
fs = require "nixio.fs"
sys = require "luci.sys"
log_file = "/tmp/scutclient.log"
log_file_backup = "/tmp/scutclient.log.backup.log"
function index()
if not fs.access("/etc/config/scutclient") then
return
end
local uci = require "luci.model.uci".cursor()
local mainorder = uci:get_first("scutclient", "luci", "mainorder", 10)
if not uci:get_first("scutclient", "luci", "configured", false) then
entry({"admin", "scutclient"},
alias("admin", "scutclient", "settings"),
"华南理工大学客户端",
mainorder
).acl_depends = { "luci-app-scutclient" }
entry({"admin", "scutclient", "settings"},
cbi("scutclient/scutclient"),
"设置",
10
).leaf = true
entry({"admin", "scutclient", "status"},
call("action_status"),
"状态",
20
).leaf = true
else
entry({"admin", "scutclient"},
alias("admin", "scutclient", "status"),
"华南理工大学客户端",
mainorder
).acl_depends = { "luci-app-scutclient" }
entry({"admin", "scutclient", "status"},
call("action_status"),
"状态",
10
).leaf = true
entry({"admin", "scutclient", "settings"},
cbi("scutclient/scutclient"),
"设置",
20
).leaf = true
end
entry({"admin", "scutclient", "logs"}, template("scutclient/logs"), "日志", 30).leaf = true
entry({"admin", "scutclient", "about"}, call("action_about"), "关于", 40).leaf = true
entry({"admin", "scutclient", "get_log"}, call("get_log"))
entry({"admin", "scutclient", "netstat"}, call("get_netstat"))
entry({"admin", "scutclient", "scutclient-log.tar"}, call("get_dbgtar"))
end
function get_log()
local send_log_lines = 75
if fs.access(log_file) then
client_log = sys.exec("tail -n "..send_log_lines.." " .. log_file)
else
client_log = "Unable to access the log file!"
end
http.prepare_content("text/plain; charset=gbk")
http.write(client_log)
http.close()
end
function action_about()
luci.template.render("scutclient/about")
end
function action_status()
luci.template.render("scutclient/status")
if luci.http.formvalue("logoff") == "1" then
luci.sys.call("/etc/init.d/scutclient stop > /dev/null")
end
if luci.http.formvalue("redial") == "1" then
luci.sys.call("/etc/init.d/scutclient stop > /dev/null")
luci.sys.call("/etc/init.d/scutclient start > /dev/null")
end
if luci.http.formvalue("move_tag") == "1" then
luci.sys.call("uci set scutclient.@luci[-1].mainorder=90")
luci.sys.call("uci commit")
luci.sys.call("rm -rf /tmp/luci-*cache")
end
end
function get_netstat()
local hcontent = sys.exec("wget -O- http://whatismyip.akamai.com 2>/dev/null | head -n1")
local nstat = {}
if hcontent == '' then
nstat.stat = 'no_internet'
elseif hcontent:find("(%d+)%.(%d+)%.(%d+)%.(%d+)") then
nstat.stat = 'internet'
else
nstat.stat = 'no_login'
end
http.prepare_content("application/json")
http.write_json(nstat)
http.close()
end
function get_dbgtar()
local tar_dir = "/tmp/scutclient-log"
local tar_files = {
"/etc/config/wireless",
"/etc/config/network",
"/etc/config/system",
"/etc/config/scutclient",
"/etc/openwrt_release",
"/etc/crontabs/root",
"/etc/config/dhcp",
"/tmp/dhcp.leases",
"/etc/rc.local",
}
fs.mkdirr(tar_dir)
table.foreach(tar_files, function(i, v)
luci.sys.call("cp " .. v .. " " .. tar_dir)
end)
if fs.access(log_file_backup) then
luci.sys.call("cat " .. log_file_backup .. " >> " .. tar_dir .. "/scutclient.log")
end
if fs.access(log_file) then
luci.sys.call("cat " .. log_file .. " >> " .. tar_dir .. "/scutclient.log")
end
http.prepare_content("application/octet-stream")
http.write(sys.exec("tar -C " .. tar_dir .. " -cf - ."))
luci.sys.call("rm -rf " .. tar_dir)
http.close()
end
@@ -0,0 +1,92 @@
-- LuCI by libc0607 (libc0607@gmail.com)
-- 华工路由群 262939451
scut = Map(
"scutclient",
"华南理工大学客户端 设置",
' <input style="margin: 2px;" class="cbi-button cbi-button-apply" type="button" value="'
.."Step 1 : 点此处去设置Wi-Fi"
..'" onclick="javascript:location.href=\''
..luci.dispatcher.build_url("admin/network/wireless/radio0.network1")
..'\'"/>'
..' <input style="margin: 2px;" class="cbi-button cbi-button-apply" type="button" value="'
.."Step 2 : 点此处去设置IP"
..'" onclick="javascript:location.href=\''
..luci.dispatcher.build_url("admin/network/network/wan")
..'\'"/>'
..' <input style="margin: 2px;" class="cbi-button cbi-button-apply" type="button" value="'
.."Step 3 : 点此处去修改路由器管理密码"
..'" onclick="javascript:location.href=\''
..luci.dispatcher.build_url("admin/system/admin")
..'\'"/>'
)
function scut.on_commit(self)
luci.sys.call("uci set scutclient.@luci[-1].configured=1")
luci.sys.call("uci commit")
luci.sys.call("rm -rf /tmp/luci-*cache")
end
-- config option
scut_option = scut:section(TypedSection, "option", translate("选项"))
scut_option.anonymous = true
scut_option:option(Flag, "enable", "启用")
-- config scutclient
scut_client = scut:section(TypedSection, "scutclient", "用户信息")
scut_client.anonymous = true
scut_client:option(Value, "username", "拨号用户名", "学校提供的用户名,一般是学号")
scut_client:option(Value, "password", "拨号密码").password = true
-- config drcom
scut_drcom = scut:section(TypedSection, "drcom", "Drcom设置")
scut_drcom.anonymous = true
scut_drcom_version = scut_drcom:option(Value, "version", "Drcom版本")
scut_drcom_version.rmempty = false
scut_drcom_version:value("4472434f4d0096022a")
scut_drcom_version:value("4472434f4d0096022a00636b2031")
scut_drcom_version:value("4472434f4d00cf072a00332e31332e302d32342d67656e65726963")
scut_drcom_version.default = "4472434f4d0096022a"
scut_drcom_hash = scut_drcom:option(Value, "hash", translate("DrAuthSvr.dll版本"))
scut_drcom_hash.rmempty = false
scut_drcom_hash:value("2ec15ad258aee9604b18f2f8114da38db16efd00")
scut_drcom_hash:value("d985f3d51656a15837e00fab41d3013ecfb6313f")
scut_drcom_hash:value("915e3d0281c3a0bdec36d7f9c15e7a16b59c12b8")
scut_drcom_hash.default = "2ec15ad258aee9604b18f2f8114da38db16efd00"
scut_drcom_server = scut_drcom:option(Value, "server_auth_ip", translate("服务器IP"))
scut_drcom_server.rmempty = false
scut_drcom_server.datatype = "ip4addr"
scut_drcom_server:value("202.38.210.131")
--[[ 主机名列表预置
1.生成一个 DESKTOP-XXXXXXX 的随机
2.dhcp分配的第一个
]]--
scut_drcom_hostname = scut_drcom:option(Value, "hostname", translate("向服务器发送的主机名"))
scut_drcom_hostname.rmempty = false
local random_hostname = "DESKTOP-"
local randtmp
-- 抄的
string.split = function(s, p)
local rt = {}
string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end)
return rt
end
math.randomseed(os.time())
for i = 1, 7 do
randtmp = math.random(1, 36)
random_hostname = (randtmp > 10)
and random_hostname..string.char(randtmp+54)
or random_hostname..string.char(randtmp+47)
end
-- 获取dhcp列表,加入第一个主机名候选
local dhcp_hostnames = string.split(luci.sys.exec("cat /tmp/dhcp.leases|awk {'print $4'}"), "\n") or {}
scut_drcom_hostname:value(random_hostname)
scut_drcom_hostname:value(dhcp_hostnames[1])
scut_drcom_hostname.default = random_hostname
return scut
@@ -0,0 +1,24 @@
<%+header%>
<h2>
<a id="about" name="about">许可证</a>
</h2>
<p style="text-align:center;">
<a href="https://www.gnu.org/licenses/agpl-3.0.html">AGPLv3</a>
</p>
<p style="text-align:center;">特别指出禁止任何个人或组织将scutclient的代码投入商业使用,由此造成的后果和法律责任后果自负。</p>
<h2>
<a id="thanks" name="thanks">致谢</a>
</h2>
<p style="text-align:center;">群主的猫<br/>ฅ(⌯͒• ɪ •⌯͒)ฅ❣</p>
<br/>
<p style="text-align:center;">
<a href="http://weibo.com/scutrouter">华工路由器群官方微博</a><br/>
QQ审核群:<a href="http://jq.qq.com/?_wv=1027&k=27KCAyx">262939451</a>
</p>
<%+footer%>
@@ -0,0 +1,67 @@
<%+header%>
<h2>
<a id="content" name="content">客户端日志</a>
</h2>
<div class="cbi-map-descr">
</div>
<table width="100%" cellspacing="10">
<tbody>
<tr class="cbi-section-table-row cbi-rowstyle-1">
<td width="33%"><strong>配置文件</strong></td>
<td><input style="margin: 2px;" class="cbi-button cbi-button-apply" type="button" value="打包下载" onclick='window.open("<%=luci.dispatcher.build_url('admin/scutclient/scutclient-log.tar')%>")'></td>
</tbody>
</table>
<h3>
scutclient日志
</h3>
<div id="content_logs">
<textarea style="font-size: 12px;" readonly="readonly" wrap="off" rows="50" id="syslog">
Collecting data...
</textarea>
</div>
<script type="text/javascript" language="javascript">
xhrobj = new XHR();
xhr_rawget = function(url,data,callback) {
xhrobj.reinit();
var xhr = xhrobj._xmlHttp;
var code = xhrobj._encode(data);
url = location.protocol + '//' + location.host + url;
if (code)
if (url.substr(url.length-1,1) == '&')
url += code;
else
url += '?' + code;
xhr.open('GET', url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
callback(xhr, xhr.responseText);
}
}
xhr.send(null);
}
readlog = function() {
if(!xhrobj.busy()) {
xhr_rawget('<%=luci.dispatcher.build_url('admin/scutclient/get_log')%>', null,
function(x, log_data) {
var syslog_id = document.getElementById("syslog");
if (typeof(log_data) != "undefined") {
syslog_id.innerHTML = log_data;
}
document.getElementById("syslog").scrollTop=document.getElementById("syslog").scrollHeight;
}
);
}
}
readlog();
window.setInterval(readlog, 3000);
</script>
<%+footer%>
@@ -0,0 +1,288 @@
<%
-- LuCI by libc0607 (libc0607@gmail.com)
-- 华工路由群:262939451
local sys = require "luci.sys"
local fs = require "nixio.fs"
local uci = require "luci.model.uci".cursor()
local ntm = require "luci.model.network".init()
local scutclient_version = luci.sys.exec("opkg list-installed scutclient | cut -d ' ' -f 3")
local scutclient_status = {}
scutclient_status.enable = uci:get_first("scutclient", "option", "enable")
scutclient_status.username = uci:get_first("scutclient", "scutclient", "username")
scutclient_status.password = uci:get_first("scutclient", "scutclient", "password")
scutclient_status.hostname = uci:get_first("scutclient", "drcom", "hostname")
scutclient_status.version = uci:get_first("scutclient", "drcom", "version")
scutclient_status.hash = uci:get_first("scutclient", "drcom", "hash")
scutclient_status.server_auth_ip = uci:get_first("scutclient", "drcom", "server_auth_ip")
local mode_links = {}
mode_links.base = luci.dispatcher.build_url("admin/scutclient/status")
mode_links.redial = mode_links.base.."?redial=1"
mode_links.logoff = mode_links.base.."?logoff=1"
mode_links.move_tag = mode_links.base .."?move_tag=1"
local stat, wan_nets = pcall(ntm.get_wan_networks, ntm)
local wan, wandev
if stat then
if #wan_nets > 0 then
wan = wan_nets[1]
wandev = wan:get_interface()
end
else
wan = ntm:get_wannet()
wandev = ntm:get_wandev()
end
function page_moved()
return (uci:get_first("scutclient", "luci", "mainorder", 10) == 10)
end
function get_client_status(exec_name)
return (os.execute("pidof scutclient > /dev/null 2>/dev/null") == 0)
end
function get_wifi_switch()
return (string.sub(luci.sys.exec("wifi status|grep up|head -n 1|awk {'print $2'}"), 1, 4) == "true")
and true
or false
end
%>
<%+header%>
<h2>
<a id="content" name="content">客户端状态</a>
</h2>
<fieldset class="cbi-section">
<legend>
<strong>状态</strong>
</legend>
<div>
<table width="100%" cellspacing="10">
<tbody>
<tr class="cbi-section-table-row cbi-rowstyle-1">
<td width="33%"><strong>scutclient</strong></td>
<% if get_client_status("scutclient") then %>
<td style="color: red;">正在运行</td>
<% else %>
<td style="color: red;">没有运行</td>
<% end %>
</tr>
<tr class="cbi-section-table-row cbi-rowstyle-2">
<% if get_wifi_switch() then -%>
<td width="33%"><strong>Wi-Fi SSID :</strong></td>
<td><%=luci.sys.exec("uci get wireless.@wifi-iface[0].ssid")%></td>
<% else %>
<td style="color: red;"><strong>Wi-Fi 状态:</strong></td>
<td style="color: red;"><strong>未开启,或路由器没有无线网卡</strong></td>
<% end %>
</tr>
<% if wan then %>
<tr class="cbi-section-table-row cbi-rowstyle-1">
<td width="33%">WAN口</td>
<td><%=wandev:name()%></td>
</tr>
<tr class="cbi-section-table-row cbi-rowstyle-2" id="all_status_ipaddr">
<td width="33%"><strong>IP地址</strong></td>
<td id="status_ipaddr"><%=wan:ipaddr()%></td>
</tr>
<tr class="cbi-section-table-row cbi-rowstyle-1">
<td width="33%"><strong>子网掩码</strong></td>
<td id="status_netmask"><%=wan:netmask()%></td>
</tr>
<tr class="cbi-section-table-row cbi-rowstyle-2" id="all_status_gateway">
<td width="33%"><strong>网关</strong></td>
<td id="status_gateway"><%=wan:gwaddr()%></td>
</tr>
<tr class="cbi-section-table-row cbi-rowstyle-1">
<td width="33%"><strong>DNS</strong></td>
<td id="status_dns"><%=table.concat(wan:dnsaddrs(), ",")%></td>
</tr>
<tr class="cbi-section-table-row cbi-rowstyle-2">
<td width="33%"><strong>MAC</strong></td>
<td id="status_macaddr"><%=wandev:mac()%></td>
</tr>
<tr class="cbi-section-table-row cbi-rowstyle-1">
<td width="33%"><strong>网络状态</strong></td>
<td id="status_net">获取中……</td>
</tr>
<% else %>
<tr class="cbi-section-table-row cbi-rowstyle-2">
<td style="color: red;"><strong id="wan_status">WAN口未正确配置</strong></td>
</tr>
<% end %>
</tbody>
</table>
</fieldset>
<fieldset class="cbi-section">
<legend>
<strong>客户端设置</strong>
</legend>
<div>
<table width="100%" cellspacing="10">
<tbody>
<tr class="cbi-section-table-row cbi-rowstyle-1">
<td width="33%"><strong>功能</strong></td>
<td>
<a href="<%=mode_links.logoff%>">下线</a>
<a href="<%=mode_links.redial%>">重拨</a>
<% if page_moved() then %>
<a href="<%=mode_links.move_tag%>">我不想每次打开都见到这个界面把它移走</a>
<% end %>
</td>
</tr>
<tr class="cbi-section-table-row cbi-rowstyle-2">
<% if string.len(scutclient_version) > 1 then %>
<td width="33%"><strong>已安装版本:</strong></td>
<td><%=scutclient_version%></td>
<% else %>
<td style="color: red;"><strong>scutclient未安装</strong></td>
<% end %>
</tr>
<tr class="cbi-section-table-row cbi-rowstyle-1">
<td width="33%"><strong>开机启动</strong></td>
<td><%=scutclient_status.enable%></td>
</tr>
<tr class="cbi-section-table-row cbi-rowstyle-2">
<td width="33%"><strong>账号</strong></td>
<% if scutclient_status.username == "root" then %>
<td style="color: red;"><%=scutclient_status.username%>。。。你的浏览器开启了自动保存帐号密码?</td>
<% else %>
<td><%=scutclient_status.username%></td>
<% end %>
</tr>
<tr class="cbi-section-table-row cbi-rowstyle-1">
<td width="33%"><strong>密码</strong></td>
<td><%=scutclient_status.password%></td>
</tr>
<tr class="cbi-section-table-row cbi-rowstyle-1">
<td width="33%"><strong>主机名</strong></td>
<td><%=scutclient_status.hostname%></td>
</tr>
<tr class="cbi-section-table-row cbi-rowstyle-2">
<td width="33%"><strong>Drcom版本</strong></td>
<td><%=scutclient_status.version%></td>
</tr>
<tr class="cbi-section-table-row cbi-rowstyle-1">
<td width="33%"><strong>Hash</strong></td>
<td><%=scutclient_status.hash%></td>
</tr>
<tr class="cbi-section-table-row cbi-rowstyle-2">
<td width="33%"><strong>服务器IP</strong></td>
<td><%=scutclient_status.server_auth_ip%></td>
</tr>
</tbody>
</table>
</fieldset>
<script type="text/javascript" language="javascript">
window.alert = function(txt){
var shield = document.createElement("DIV");
shield.id = "shield";
shield.style.position = "absolute";
shield.style.left = "0px";
shield.style.top = "0px";
shield.style.width = "100%";
shield.style.height = document.body.scrollHeight+"px";
shield.style.background = "#333";
shield.style.textAlign = "center";
shield.style.zIndex = "10000";
shield.style.filter = "alpha(opacity=0)";
var alertFram = document.createElement("DIV");
alertFram.id="alertFram";
alertFram.style.position = "absolute";
alertFram.style.left = "50%";
alertFram.style.top = "50%";
alertFram.style.marginLeft = "-225px";
alertFram.style.marginTop = "-75px";
alertFram.style.width = "450px";
alertFram.style.height = "150px";
alertFram.style.background = "#ccc";
alertFram.style.textAlign = "center";
alertFram.style.lineHeight = "150px";
alertFram.style.zIndex = "10001";
strHtml = "<ul class='ifacebox' style='list-style:none;margin:0px;padding:0px;width:100%'>";
strHtml += " <li class='ifacebox-head' style='background:#DD828D;text-align:center;padding-left:20px;font-size:16px;font-weight:bold;height:25px;line-height:25px;border:1px solid #F9CADE;'><strong>温馨提示</strong></li>";
strHtml += " <li class='ifacebox-body' style='background:#fff;text-align:center;font-size:20px;height:120px;line-height:40px;border-left:1px solid #F9CADE;border-right:1px solid #F9CADE;'onclick='doOk()'>"+txt+"</li>";
strHtml += "</ul>";
alertFram.innerHTML = strHtml;
document.body.appendChild(alertFram);
this.doOk = function(){
alertFram.style.display = "none";
shield.style.display = "none";
}
alertFram.focus();
document.body.onselectstart = function(){return false;};
}
if(document.getElementById("wan_status") == null)
{
var ip = document.getElementById("status_ipaddr").innerHTML;
var gateway = document.getElementById("status_gateway").innerHTML;
var isCorrect = true;
for (var i=0;i<3;i++)
{
isCorrect = isCorrect && (parseInt(ip.match(/\d+/g)[i]) == parseInt(gateway.match(/\d+/g)[i]));
}
if(!isCorrect)
{
alert( ip + "<br/>"+ gateway +"<br/>前三位不一致,请看教程三遍!");
document.getElementById("all_status_ipaddr").style.color="red";
document.getElementById("all_status_gateway").style.color="red";
}
else
{
document.getElementById("all_status_ipaddr").style.color="black";
document.getElementById("all_status_gateway").style.color="black";
}
}
XHR.get('<%=luci.dispatcher.build_url("admin", "scutclient", "netstat")%>', null, function(xhr, res) {
var statstr = "网络状态获取错误!";
var statelem = document.getElementById("status_net");
if (res !== null && typeof(res) === 'object') {
if (res['stat'] == 'internet') {
statstr = "网络正常";
statelem.style = "color: green";
} else if (res['stat'] == 'no_login') {
statstr = "校园网未登录";
statelem.style = "color: #FFA500";
} else if (res['stat'] == 'no_internet') {
statstr = "网络错误!检查网线/IP设置!";
statelem.style = "color: red";
}
}
statelem.innerHTML = statstr;
});
</script>
<%+footer%>