update 2025-02-09 16:14:09

This commit is contained in:
kenzok8 2025-02-09 16:14:09 +08:00
parent 7c322735ed
commit 6b8c92ac4f
14 changed files with 313 additions and 137 deletions

View File

@ -816,7 +816,7 @@ gen_dns(){
rm -f $O
[ $(find $DNS_DIR -name \* -exec cat {} \; 2>/dev/null | wc -l) = 0 ] && rm -rf $DNS_DIR || echo conf-dir=$DNS_DIR >>$DNS_FILE
[ $run_mode = router ] && chinadns_flag=1
killall -q -9 smartdns
killall -q smartdns
start_dns
/etc/init.d/dnsmasq restart >/dev/null 2>&1
preload
@ -1011,7 +1011,7 @@ stop(){
kill -9 $(ps -w | grep by-monitor | grep -v grep | awk '{print$1}') 2>/dev/null
kill -9 $(ps -w | grep by-preload | grep -v grep | awk '{print$1}') 2>/dev/null
kill -9 $(ps -w | grep $VAR | grep -v grep | awk '{print$1}') 2>/dev/null
killall -q -9 smartdns chinadns-ng kcptun-client microsocks
killall -q smartdns chinadns-ng kcptun-client microsocks
rm -rf $DNS_DIR $VAR $DNS_FILE $CON_T /var/lock/bypass-update.lock
[ -z "$GLOBAL_SERVER" ] && grep -q bypass $CRON_FILE && sed -i '/bypass/d' $CRON_FILE && /etc/init.d/cron restart
if [ $STATUS = Y -o -z "$GLOBAL_SERVER" ];then

View File

@ -444,10 +444,6 @@ restart(){
fi
}
service_triggers() {
procd_add_reload_trigger "dnsfilter"
}
boot(){
gen;start
}

View File

@ -7,7 +7,7 @@ function index()
end
local page
entry({"admin", "services", "appfilter"}, alias("admin", "services", "appfilter", "user_list"),_("App Filter"), 10).dependent = true
entry({"admin", "services", "appfilter"}, alias("admin", "services", "appfilter", "app_filter"),_("App Filter"), 10).dependent = true
entry({"admin", "services", "appfilter", "user_list"},

View File

@ -32,10 +32,10 @@ if nixio.fs.access("/tmp/feature.cfg") then
rule_count = tonumber(SYS.exec("cat /tmp/feature.cfg | grep -v ^$ |grep -v ^# | wc -l"))
version = SYS.exec("cat /tmp/feature.cfg |grep \"#version\" | awk '{print $2}'")
end
format=SYS.exec("uci get appfilter.feature.format")
if format == "" then
format="v3.0"
end
-- format=SYS.exec("uci get appfilter.feature.format")
-- if format == "" then
format="v3.0"
-- end
local display_str = "<style>" ..
".label-style {}" ..

View File

@ -101,7 +101,7 @@
.button-container {
display: flex;
justify-content: right;
margin-top: 20px;
margin-top: 5px;
}
.submit-button {
@ -236,7 +236,7 @@
const container = document.getElementById('appContainer');
container.innerHTML = '';
data.class_list.forEach(category => {
data.class_list.forEach((category, index) => {
const categoryTitle = document.createElement('div');
categoryTitle.className = 'category-title';
@ -267,7 +267,13 @@
const appList = document.createElement('div');
appList.className = 'app-list';
appList.style.display = 'none';
if (index === 1 || index === 2) {
appList.style.display = 'flex';
arrow.classList.add('expanded');
} else {
appList.style.display = 'none';
}
categoryTitle.onclick = function() {
if (appList.style.display === 'none') {

View File

@ -17,77 +17,76 @@
.app-list {
display: flex;
flex-wrap: wrap;
justify-content: flex-start; /* 左对齐 */
margin-top: 10px; /* 增加与标题的间距 */
justify-content: flex-start;
margin-top: 10px;
}
.app-item {
width: 140px; /* 固定宽度 */
width: 140px;
box-sizing: border-box;
padding: 5px;
display: flex; /* 使用flex布局 */
align-items: center; /* 垂直居中 */
display: flex;
align-items: center;
}
.app-item label {
display: flex; /* 使用flex布局 */
align-items: center; /* 垂直居中 */
width: 100%; /* 确保标签占满整个宽度 */
text-align: left; /* 左对齐文本 */
display: flex;
align-items: center;
width: 100%;
text-align: left;
}
.app-item input[type="checkbox"] {
margin-left: 2px; /* 勾选按钮离左侧2px */
margin-right: 8px; /* 应用程序名称离按钮8px */
margin-left: 2px;
margin-right: 8px;
}
h2 {
margin-bottom: 10px;
}
.category-title {
display: flex; /* 使用flex布局 */
justify-content: space-between; /* 两端对齐 */
align-items: center; /* 垂直居中 */
width: 100%; /* 设置宽度为100% */
cursor: pointer; /* 鼠标悬停时显示为可点击 */
margin-bottom: 10px; /* 增加下方间距 */
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
cursor: pointer;
margin-bottom: 10px;
}
.category-name {
font-size: 14px; /* 设置字体大小为16px */
font-weight: normal; /* 设置字体为正常,不加粗 */
font-size: 14px;
font-weight: normal;
}
.arrow {
width: 12px; /* 图标宽度 */
height: 12px; /* 图标高度 */
/* background-image: url('path/to/your/icon.svg'); 替换为你的图标路径 */
width: 12px;
height: 12px;
background-image: url('<%=resource%>/icons/arrow.png'); /* 使用LuCI资源路径 */
background-size: contain; /* 确保图标适应容器 */
background-repeat: no-repeat; /* 防止重复 */
transition: transform 0.3s ease; /* 添加过渡效果 */
display: inline-block; /* 使旋转生效 */
transform: rotate(0deg); /* 初始状态箭头向右 */
background-image: url('<%=resource%>/icons/arrow.png');
background-size: contain;
background-repeat: no-repeat;
transition: transform 0.3s ease;
display: inline-block;
transform: rotate(0deg);
}
.arrow.expanded {
transform: rotate(90deg); /* 展开状态箭头向下 */
transform: rotate(90deg);
}
.category-title div {
gap: 6px; /* 设置子元素之间的间距为20px */
gap: 6px;
}
@media (max-width: 600px) {
.app-item {
width: 25%; /* 屏幕小于600px时每行显示4个 */
width: 25%;
}
}
.button-container {
display: flex;
justify-content: right; /* 使按钮居中 */
margin-top: 20px; /* 上方留出一些空间 */
justify-content: right;
margin-top: 20px;
}
.submit-button {
margin-top: 30px;
width: 150px; /* 设置按钮宽度 */
height: 30px; /* 设置按钮高度 */
width: 150px;
height: 30px;
background-color: #2885e8;
color: white;
border: none;
@ -98,7 +97,6 @@
background-color: #0f77e6;
}
/* Add new styles for time rules */
.time-rules {
margin-top: 20px;
border: 1px solid #ddd;
@ -147,7 +145,7 @@
}
.setting-item label {
display: inline-block;
width: 150px;
width: 170px;
}
.setting-item input {
width: 100px;
@ -209,11 +207,9 @@
function init_data() {
// getAppFilterData().then(() => {
// getClassListData();
// });
// getAppFilterBaseData(); // 新增调用获取过滤开关和工作模式数据的函数
getAppFilterTimeData();
getAppFilterTimeData().then(() => {
renderTimeData();
});
}
function getAppFilterTimeData() {
@ -222,8 +218,7 @@
function (x, data) {
time_data = data.data;
console.log(data.data);
renderTimeData();
resolve(); // 请求完成后调用 resolve
resolve();
}
);
});
@ -232,19 +227,34 @@
function submitHandle() {
const time_data = getTimeFormData();
const maxEntries = 64;
if (!time_data.time_list || time_data.time_list.length === 0) {
const errorContainer = document.getElementById('errorContainer');
errorContainer.innerHTML = '至少添加一个时间段';
return;
}
if (time_data.time_list.length > maxEntries) {
const errorContainer = document.getElementById('errorContainer');
errorContainer.innerHTML = '时间段不能超过64条';
return;
}
console.log('Time Rules:', time_data);
const data = {
data: time_data
}
new XHR().post('<%=url('admin/network/set_app_filter_time')%>', data,
function (x, data) {
init_data();
const modal = document.getElementById('modal');
modal.style.display = 'flex'; // 显示模态框
setTimeout(() => {
modal.style.display = 'none'; // 3秒后自动隐藏模态框
}, 1000); }
);
const data = {
data: time_data
};
new XHR().post('<%=url('admin/network/set_app_filter_time')%>', data,
function (x, data) {
init_data();
const modal = document.getElementById('modal');
modal.style.display = 'flex';
setTimeout(() => {
modal.style.display = 'none';
}, 1000);
}
);
}
function openModal() {
@ -255,7 +265,6 @@
document.getElementById('modal').style.display = 'none';
}
// 新增获取过滤开关和工作模式数据的函数
function getAppFilterBaseData() {
console.log("getAppFilterBaseData");
new XHR().get('<%=url('admin/network/get_app_filter_base')%>', null,
@ -265,7 +274,6 @@
} else {
document.getElementById('filterSwitch').checked = false;
}
// 直接使用接口返回的work_mode值来设置选中的选项
document.getElementById('workMode').value = data.data.work_mode;
console.log("Base filter settings loaded");
}
@ -278,9 +286,18 @@
row.innerHTML = `
<td><input type="time" class="start-time" required></td>
<td><input type="time" class="end-time" required></td>
<td><button class="delete-time-btn" onclick="deleteTimeRow(this)">删除</button></td>
<td><button type="button" class="delete-time-btn" onclick="deleteTimeRow(this)">删除</button></td>
`;
tbody.appendChild(row);
setTimeout(() => {
const startTimeInput = row.querySelector('.start-time');
const endTimeInput = row.querySelector('.end-time');
startTimeInput.value = "00:00";
endTimeInput.value = "23:59";
}, 0);
addTimeValidation();
}
function deleteTimeRow(btn) {
@ -317,14 +334,14 @@
weekday_list: weekdays
};
if (mode === "0") { // 固定时间模式
if (mode === "0") {
const time_list = Array.from(document.getElementById('timeTableBody').rows)
.map(row => ({
start: row.querySelector('.start-time').value,
end: row.querySelector('.end-time').value
}));
timeData.time_list = time_list;
} else { // 动态时间模式
} else {
timeData.start_time = document.getElementById('startTime').value;
timeData.end_time = document.getElementById('endTime').value;
timeData.allow_time = parseInt(document.getElementById('allowTime').value);
@ -339,30 +356,66 @@
element.nextElementSibling.classList.toggle('expanded');
}
function addTimeValidation() {
document.querySelectorAll('.start-time, .end-time').forEach(input => {
input.addEventListener('blur', validateTime);
});
}
function validateTime(event) {
const row = event.target.closest('tr');
const startTimeInput = row.querySelector('.start-time');
const endTimeInput = row.querySelector('.end-time');
const startTime = startTimeInput.value;
const endTime = endTimeInput.value;
const errorContainer = document.getElementById('errorContainer');
errorContainer.innerHTML = '';
let errorMessage = '';
if (!isValidTimeFormat(startTime) || !isValidTimeFormat(endTime)) {
errorMessage = '时间格式不合法,请输入有效的时间格式 (HH:MM)';
} else if (startTime >= endTime) {
errorMessage = '结束时间必须大于开始时间';
}
if (errorMessage) {
const errorElement = document.createElement('div');
errorElement.className = 'error-message';
errorElement.style.color = 'red';
errorElement.style.fontSize = '12px';
errorElement.textContent = errorMessage;
errorContainer.appendChild(errorElement);
}
}
function isValidTimeFormat(time) {
const timePattern = /^([01]\d|2[0-3]):([0-5]\d)$/;
return timePattern.test(time);
}
function renderTimeData() {
// Set mode
const timeMode = document.getElementById('timeMode');
timeMode.value = time_data.mode
toggleModeContent();
timeMode.value = time_data.mode;
// Set weekday checkboxes based on mode
// Clear previous selections
document.querySelectorAll('input[name="weekday"]').forEach(cb => cb.checked = false);
// Set weekday checkboxes for both modes
time_data.weekday_list.forEach(day => {
if (time_data.mode === 0) {
// For static mode, set checkboxes in staticWeekdaySelector
const checkbox = document.querySelector('#staticWeekdaySelector input[name="weekday"][value="' + day + '"]');
if (checkbox) checkbox.checked = true;
} else {
// For dynamic mode, set checkboxes in advanced-content
const checkbox = document.querySelector('.advanced-content input[name="weekday"][value="' + day + '"]');
if (checkbox) checkbox.checked = true;
}
const staticCheckbox = document.querySelector(`#staticWeekdaySelector input[name="weekday"][value="${day}"]`);
const dynamicCheckbox = document.querySelector(`.advanced-content input[name="weekday"][value="${day}"]`);
if (staticCheckbox) staticCheckbox.checked = true;
if (dynamicCheckbox) dynamicCheckbox.checked = true;
});
if (time_data.mode === 0) {
// Render time ranges
const tbody = document.getElementById('timeTableBody');
tbody.innerHTML = '';
// Render static mode data
const tbody = document.getElementById('timeTableBody');
tbody.innerHTML = '';
if (time_data.time_list) {
time_data.time_list.forEach(timeRange => {
const row = document.createElement('tr');
row.innerHTML = `
@ -372,27 +425,60 @@
`;
tbody.appendChild(row);
});
} else { // 动态时间模式
if (time_data.start_time || time_data.end_time) {
// If we have time data, expand the advanced settings
const advancedToggle = document.querySelector('.advanced-toggle');
if (advancedToggle) {
toggleAdvanced(advancedToggle);
}
}
if (time_data.start_time) {
document.getElementById('startTime').value = time_data.start_time;
}
if (time_data.end_time) {
document.getElementById('endTime').value = time_data.end_time;
}
if (time_data.allow_time) {
document.getElementById('allowTime').value = time_data.allow_time;
}
if (time_data.deny_time) {
document.getElementById('denyTime').value = time_data.deny_time;
}
}
// Render dynamic mode data
if (time_data.start_time) {
document.getElementById('startTime').value = time_data.start_time;
}
if (time_data.end_time) {
document.getElementById('endTime').value = time_data.end_time;
}
if (time_data.allow_time) {
document.getElementById('allowTime').value = time_data.allow_time;
}
if (time_data.deny_time) {
document.getElementById('denyTime').value = time_data.deny_time;
}
// Ensure the correct content is displayed based on the mode
toggleModeContent();
// Add validation to time inputs
addTimeValidation();
}
function validateDynamicTime() {
const startTimeInput = document.getElementById('startTime');
const endTimeInput = document.getElementById('endTime');
const dynamicErrorContainer = document.getElementById('dynamicErrorContainer');
dynamicErrorContainer.innerHTML = ''; // 清空之前的错误信息
const startTime = startTimeInput.value;
const endTime = endTimeInput.value;
let errorMessage = '';
if (!isValidTimeFormat(startTime) || !isValidTimeFormat(endTime)) {
errorMessage = '时间格式不合法,请输入有效的时间格式 (HH:MM)';
} else if (startTime >= endTime) {
errorMessage = '结束时间必须大于开始时间';
}
if (errorMessage) {
const errorElement = document.createElement('div');
errorElement.className = 'error-message';
errorElement.style.color = 'red';
errorElement.style.fontSize = '12px';
errorElement.textContent = errorMessage;
dynamicErrorContainer.appendChild(errorElement);
}
}
function isValidTimeFormat(time) {
const timePattern = /^([01]\d|2[0-3]):([0-5]\d)$/;
return timePattern.test(time);
}
window.onload = init_data;
@ -434,7 +520,7 @@
<div class="weekday-item"><input type="checkbox" name="weekday" value="6"> 周六</div>
<div class="weekday-item"><input type="checkbox" name="weekday" value="0"> 周日</div>
</div>
<!-- 固定时间模式内容 -->
<div id="staticTimeContent">
<table class="time-table">
@ -447,26 +533,28 @@
</thead>
<tbody id="timeTableBody">
</tbody>
</table>
</table>
<div id="errorContainer" style="color: red; font-size: 12px; margin-top: 10px;"></div>
<button class="add-time-btn" onclick="addTimeRow()">添加时间段</button>
</div>
<!-- 动态时间模式内容 -->
<div id="dynamicTimeContent" style="display: none;">
<div style="color: #666; font-size: 13px; margin-bottom: 15px;">
动态时间是指动态调整应用过滤开关比如小孩学习1个小时后奖励20分钟玩游戏
动态时间模式是指动态调整应用过滤开关比如小孩学习1个小时后奖励20分钟玩游戏,超过娱乐时间后自动开启过滤,反复循环。
</div>
<div class="dynamic-time-settings">
<div class="setting-item">
<label>每次启用时长(学习时间):</label>
<input type="number" id="denyTime" min="1" value="5">
<input type="number" id="denyTime" min="1" value="60">
<span>分钟</span>
</div>
<div class="setting-item" style="margin-bottom: 15px;">
<label>每次关闭时长(课余时间):</label>
<input type="number" id="allowTime" min="1" value="30">
<input type="number" id="allowTime" min="1" value="10">
<span>分钟</span>
</div>
@ -490,9 +578,9 @@
<div class="setting-item">
<label>每天学习时间范围:</label>
<input type="time" id="startTime" required style="margin-right: 5px;">
<input type="time" id="startTime" required style="margin-right: 5px;" onchange="validateDynamicTime()">
<span>-</span>
<input type="time" id="endTime" required style="margin-left: 5px;">
<input type="time" id="endTime" required style="margin-left: 5px;" onchange="validateDynamicTime()">
</div>
<div class="setting-item" style="color: #666; font-size: 12px; margin-top: 5px;">
<span>该时间范围表示每天上学的时间段,是一段连续时间,在该时间段内实行过滤规则动态开启关闭,时间范围外默认关闭过滤</span>
@ -500,6 +588,7 @@
</div>
</div>
</div>
<div id="dynamicErrorContainer" style="color: red; font-size: 12px; margin-top: 10px;"></div>
</div>
</div>

View File

@ -359,7 +359,7 @@
<div id="modal" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.5); z-index: 1000; justify-content: center; align-items: center;">
<div style="background-color: rgba(0, 0, 0, 0.5); padding: 10px; border-radius: 5px; text-align: center; width: 100px; height: 70px; color: white; display: flex; justify-content: center; align-items: center;">
<div style="background-color: rgba(0, 0, 0, 0.5); padding: 10px; border-radius: 5px; text-align: center; width: 130px; height: 70px; color: white; display: flex; justify-content: center; align-items: center;">
<p style="margin: 0;">设置成功</p>
</div>
</div>

View File

@ -106,6 +106,9 @@
var tr = tb.insertRow(-1);
tr.className = 'tr';
if (user_list[i].online != 1) {
tr.style.color = '#A9A9A9'; // 设置离线行的字体颜色为浅灰色
}
tr.insertCell(-1).innerHTML = `
<div style="display: flex; align-items: center;">
<div>
@ -123,7 +126,9 @@
return `<img src="<%=resource%>/app_icons/${app.id}.png" alt="${app.name}" title="${app.name}" style="width: 20px; height: 20px; border-radius: 5px; margin-right: 8px;">`;
}).join("") || "--";
tr.insertCell(-1).innerHTML = app_list_str;
tr.insertCell(-1).innerHTML = user_list[i].online == 1 ? "<%:Online%>" : "<%:Offline%>";
tr.insertCell(-1).innerHTML = user_list[i].online == 1
? `<span style="color: green;"><%:Online%></span>`
: "<%:Offline%>";
tr.insertCell(-1).innerHTML = `
<button type="button" class="cbi-button cbi-button-add" onclick="showDetails('${user_list[i].mac}')" style="margin-right: 5px;">查看详情</button>
<button type="button" class="cbi-button cbi-button-add" onclick="showModifyNickname('${user_list[i].mac}')">修改备注</button>

View File

@ -122,7 +122,6 @@ int validate_range_value(char *range_str)
}
else
{
printk("error, invalid char %x\n", *p);
return 0;
}
}
@ -317,7 +316,7 @@ int add_app_feature(int appid, char *name, char *feature)
proto = IPPROTO_UDP;
else
{
printk("proto %s is not support\n", proto_str);
printk("proto %s is not support, feature = %s\n", proto_str, feature);
return -1;
}
sscanf(src_port_str, "%d", &src_port);
@ -827,7 +826,7 @@ int af_match_by_pos(flow_info_t *flow, af_feature_node_t *node)
}
if (strlen(node->search_str) > 0){
if (k_memstr(flow->l4_data, node->search_str, flow->l4_len)){
printk("match by search str, appid=%d, search_str=%s\n", node->app_id, node->search_str);
AF_DEBUG("match by search str, appid=%d, search_str=%s\n", node->app_id, node->search_str);
return AF_TRUE;
}
else{
@ -938,7 +937,7 @@ int match_feature(flow_info_t *flow)
{
if (af_match_one(flow, node))
{
printk("match feature, appid=%d, feature = %s\n", node->app_id, node->feature);
AF_LMT_INFO("match feature, appid=%d, feature = %s\n", node->app_id, node->feature);
flow->app_id = node->app_id;
flow->feature = node;
strncpy(flow->app_name, node->app_name, sizeof(flow->app_name) - 1);

View File

@ -1,6 +1,7 @@
config global global
option enable '0'
option work_mode '0'
option record_enable '1'
config appfilter appfilter

View File

@ -170,7 +170,6 @@ appfilter_handle_dev_visit_list(struct ubus_context *ctx, struct ubus_object *ob
printf("mac is null\n");
return 0;
}
printf("%s %d\n", __func__, __LINE__);
char *mac = json_object_get_string(mac_obj);
dev_node_t *node = find_dev_node(mac);
@ -330,6 +329,33 @@ appfilter_handle_visit_list(struct ubus_context *ctx, struct ubus_object *obj,
ubus_send_reply(ctx, req, b.head);
return 0;
}
static int handle_debug(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg)
{
int ret;
blob_buf_init(&b, 0);
char *msg_obj_str = blobmsg_format_json(msg, true);
if (!msg_obj_str)
{
printf("format json failed\n");
return 0;
}
struct json_object *req_obj = json_tokener_parse(msg_obj_str);
struct json_object *debug_obj = json_object_object_get(req_obj, "debug");
if (debug_obj)
{
current_log_level = json_object_get_int(debug_obj);
LOG_WARN("debug level set to %d\n", current_log_level);
}
ubus_send_reply(ctx, req, b.head);
return 0;
}
typedef struct app_visit_time_info
{
@ -992,7 +1018,9 @@ void all_users_callback(void *arg, dev_node_t *dev)
struct json_object *user_obj = json_object_new_object();
json_object_object_add(user_obj, "mac", json_object_new_string(dev->mac));
json_object_object_add(user_obj, "online", json_object_new_int(1));
json_object_object_add(user_obj, "online", json_object_new_int(dev->online));
json_object_object_add(user_obj, "online_time", json_object_new_int(dev->online_time));
json_object_object_add(user_obj, "offline_time", json_object_new_int(dev->offline_time));
if (flag > 0) {
json_object_object_add(user_obj, "ip", json_object_new_string(dev->ip));
@ -1025,11 +1053,46 @@ void all_users_callback(void *arg, dev_node_t *dev)
json_object_array_add(users_array, user_obj);
}
int compare_users(const void *a, const void *b)
{
struct json_object *user_a = *(struct json_object **)a;
struct json_object *user_b = *(struct json_object **)b;
struct json_object *online_a, *online_b;
json_object_object_get_ex(user_a, "online", &online_a);
json_object_object_get_ex(user_b, "online", &online_b);
int online_val_a = json_object_get_int(online_a);
int online_val_b = json_object_get_int(online_b);
if (online_val_a != online_val_b)
return online_val_b - online_val_a;
struct json_object *online_time_a, *online_time_b;
json_object_object_get_ex(user_a, "online_time", &online_time_a);
json_object_object_get_ex(user_b, "online_time", &online_time_b);
int online_time_val_a = json_object_get_int(online_time_a);
int online_time_val_b = json_object_get_int(online_time_b);
if (online_val_a == 1 && online_val_b == 1) {
// Both are online, sort by online_time
return online_time_val_a - online_time_val_b;
} else {
// Both are offline, sort by offline_time
struct json_object *offline_time_a, *offline_time_b;
json_object_object_get_ex(user_a, "offline_time", &offline_time_a);
json_object_object_get_ex(user_b, "offline_time", &offline_time_b);
int offline_time_val_a = json_object_get_int(offline_time_a);
int offline_time_val_b = json_object_get_int(offline_time_b);
return offline_time_val_a - offline_time_val_b;
}
}
static int handle_get_all_users(struct ubus_context *ctx, struct ubus_object *obj,
struct ubus_request_data *req, const char *method,
struct blob_attr *msg) {
struct json_object *response = json_object_new_object();
struct json_object *data_obj = json_object_new_object();
@ -1065,6 +1128,9 @@ static int handle_get_all_users(struct ubus_context *ctx, struct ubus_object *ob
update_dev_nickname();
dev_foreach(&au_info, all_users_callback);
// 对 users_array 进行排序
json_object_array_sort(au_info.users_array, compare_users);
json_object_object_add(data_obj, "list", au_info.users_array);
@ -1409,8 +1475,12 @@ static struct ubus_method appfilter_object_methods[] = {
UBUS_METHOD("add_app_filter_user", handle_add_app_filter_user, empty_policy),
UBUS_METHOD("set_nickname", handle_set_nickname, empty_policy),
UBUS_METHOD("get_oaf_status", handle_get_oaf_status, empty_policy),
UBUS_METHOD("debug", handle_debug, empty_policy),
};
static struct ubus_object_type main_object_type =
UBUS_OBJECT_TYPE("appfilter", appfilter_object_methods);

View File

@ -177,8 +177,14 @@ void update_dev_hostname(void)
sscanf(line_buf, "%*s %s %s %s", mac_buf, ip_buf, hostname_buf);
dev_node_t *node = find_dev_node(mac_buf);
if (!node)
continue;
if (strlen(hostname_buf) > 0)
{
node = add_dev_node(mac_buf);
strncpy(node->ip, ip_buf, sizeof(node->ip));
node->online = 0;
node->offline_time = get_timestamp();
}
if (strlen(hostname_buf) > 0 && hostname_buf[0] != '*')
{
strncpy(node->hostname, hostname_buf, sizeof(node->hostname));
}
@ -365,7 +371,7 @@ int check_dev_expire(void)
}
}
expire_count++;
printf("dev:%s expired, offline time = %ds, count=%d, visit_count=%d\n",
LOG_WARN("dev:%s expired, offline time = %ds, count=%d, visit_count=%d\n",
node->mac, offline_time, expire_count, visit_count);
}
NEXT:
@ -430,8 +436,6 @@ void dump_dev_list(void)
char hostname_buf[MAX_HOSTNAME_SIZE] = {0};
char ip_buf[MAX_IP_LEN] = {0};
FILE *fp = fopen(OAF_DEV_LIST_FILE, "w");
if (!fp)
{

View File

@ -126,6 +126,12 @@ void af_load_global_config(af_global_config_t *config){
else
config->enable = ret;
ret = af_uci_get_int_value(ctx, "appfilter.global.record_enable");
if (ret < 0)
config->record_enable = 0;
else
config->record_enable = ret;
ret = af_uci_get_int_value(ctx, "appfilter.global.user_mode");
if (ret < 0)
config->user_mode = 0;
@ -291,7 +297,6 @@ void dev_list_timeout_handler(struct uloop_timeout *t)
count++;
if (count % 10 == 0){
update_dev_list();
dump_dev_list();
}
if (count % 60 == 0){
check_dev_visit_info_expire();
@ -301,6 +306,7 @@ void dev_list_timeout_handler(struct uloop_timeout *t)
}
flush_expire_visit_info();
update_oaf_status();
dump_dev_list();
}
if (g_oaf_config_change == 1){
update_lan_ip();

View File

@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=v2rayA
PKG_VERSION:=2.2.6.3
PKG_VERSION:=2.2.6.4
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/v2rayA/v2rayA/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=62add8605c42e8e91b5fae22e3b05d146cdeea8fec44089fc1bf0ae29fc76dc0
PKG_HASH:=801873bb5d8f3fe3d27b26b8b9b4876d7dbd4ffee433344169cc5ebf8070499d
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)/service
PKG_LICENSE:=AGPL-3.0-only
@ -60,7 +60,7 @@ define Download/v2raya-web
URL:=https://github.com/v2rayA/v2rayA/releases/download/v$(PKG_VERSION)/
URL_FILE:=web.tar.gz
FILE:=$(WEB_FILE)
HASH:=e8bca04deaec72e3323310bc114fa4936474adcbb6638ec2e31dbdf88beabdae
HASH:=7625e71d9592855dc283b28eabd740d2c2851c7755e893005fc57aca03f9760f
endef
define Build/Prepare