diff --git a/adbyby/Makefile b/adbyby/Makefile
new file mode 100644
index 000000000..831dcb5b6
--- /dev/null
+++ b/adbyby/Makefile
@@ -0,0 +1,76 @@
+#
+# Copyright (C) 2015-2016 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v3.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=adbyby
+PKG_VERSION:=2.7
+PKG_RELEASE:=20200315
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/$(PKG_NAME)
+ SECTION:=net
+ CATEGORY:=Network
+ TITLE:=Powerful adblock module to block ad.
+ DEPENDS:=@(i386||x86_64||arm||mipsel||mips||aarch64)
+ URL:=http://www.adbyby.com/
+endef
+
+define Package/$(PKG_NAME)/description
+Adbyby is a powerful adblock module to block ad,just like adblock.
+endef
+
+ifeq ($(ARCH),x86_64)
+ ADBYBY_DIR:=amd64
+endif
+ifeq ($(ARCH),mipsel)
+ ADBYBY_DIR:=mipsle
+endif
+ifeq ($(ARCH),mips)
+ ADBYBY_DIR:=mips
+endif
+ifeq ($(ARCH),i386)
+ ADBYBY_DIR:=x86
+endif
+ifeq ($(ARCH),arm)
+ ADBYBY_DIR:=armv7
+ ifeq ($(BOARD),bcm53xx)
+ ADBYBY_DIR:=arm
+ endif
+ ifeq ($(BOARD),kirkwood)
+ ADBYBY_DIR:=arm
+ endif
+endif
+ifeq ($(ARCH),aarch64)
+ ADBYBY_DIR:=armv7
+endif
+
+define Build/Prepare
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+endef
+
+define Package/$(PKG_NAME)/install
+ $(INSTALL_DIR) $(1)/usr/share/adbyby
+ $(INSTALL_BIN) ./files/adbyby.sh $(1)/usr/share/adbyby/
+ $(INSTALL_CONF) ./files/adhook.ini $(1)/usr/share/adbyby/
+ $(INSTALL_CONF) ./files/user.action $(1)/usr/share/adbyby/
+
+ $(INSTALL_DIR) $(1)/usr/share/adbyby/data
+ $(INSTALL_DATA) ./files/data/* $(1)/usr/share/adbyby/data/
+
+ $(INSTALL_DIR) $(1)/usr/share/adbyby/doc
+ $(INSTALL_DATA) ./files/doc/* $(1)/usr/share/adbyby/doc/
+
+ $(INSTALL_BIN) ./files/$(ADBYBY_DIR)/adbyby $(1)/usr/share/adbyby/adbyby
+endef
+
+$(eval $(call BuildPackage,$(PKG_NAME)))
diff --git a/adbyby/files/adbyby.sh b/adbyby/files/adbyby.sh
new file mode 100755
index 000000000..146a070d1
--- /dev/null
+++ b/adbyby/files/adbyby.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+PROG_PATH=/usr/share/adbyby
+err=0
+until [ $err -ge 5 ]; do
+ if [ -n "$(pgrep $PROG_PATH/adbyby)" ]; then
+ iptables-save | grep ADBYBY >/dev/null || \
+ /etc/init.d/adbyby add_rule
+ sleep 10
+ err=0
+ else
+ $PROG_PATH/adbyby --no-daemon &>/dev/null &
+ sleep 1
+ err=$((err+1))
+ fi
+done
+/etc/init.d/adbyby del_rule
diff --git a/adbyby/files/adhook.ini b/adbyby/files/adhook.ini
new file mode 100644
index 000000000..6a7613ea8
--- /dev/null
+++ b/adbyby/files/adhook.ini
@@ -0,0 +1,14 @@
+[cfg]
+### 2.1 ###
+listen-address=0.0.0.0:8118
+buffer-limit=1024
+keep-alive-timeout=30
+socket-timeout=60
+### 2.5 ###
+max_client_connections=0
+### 2.6 ###
+stack_size=200
+auto_restart=0
+### 2.7 ###
+debug=0
+ipset=0
diff --git a/adbyby/files/amd64/adbyby b/adbyby/files/amd64/adbyby
new file mode 100755
index 000000000..76c8fa084
Binary files /dev/null and b/adbyby/files/amd64/adbyby differ
diff --git a/adbyby/files/arm/adbyby b/adbyby/files/arm/adbyby
new file mode 100755
index 000000000..a7da1900d
Binary files /dev/null and b/adbyby/files/arm/adbyby differ
diff --git a/adbyby/files/armv7/adbyby b/adbyby/files/armv7/adbyby
new file mode 100755
index 000000000..98dbfbe54
Binary files /dev/null and b/adbyby/files/armv7/adbyby differ
diff --git a/adbyby/files/data/lazy.bin b/adbyby/files/data/lazy.bin
new file mode 100644
index 000000000..23e6a8d70
Binary files /dev/null and b/adbyby/files/data/lazy.bin differ
diff --git a/adbyby/files/data/lazy.txt b/adbyby/files/data/lazy.txt
new file mode 100644
index 000000000..5d383c711
--- /dev/null
+++ b/adbyby/files/data/lazy.txt
@@ -0,0 +1,25 @@
+! -----ʱ: 2018-10-08 23:07:52 by:xwhyc-----
+.php?ad=
+/99rejs/js
+/agetsou.js^
+/c@*!25.js|$script
+/cococ-66/$script
+/defaultts.tc.qq.com/*.ts?index=0&start=0&
+/defaultts.tc.qq.com/*.ts?index=0&start=0&end=*&ver=4
+/gg_js/
+/imgs.js?t=
+/js/adtop.js|
+/js/guanggao_gg.js?d=
+/js/sss/ad.js
+/static/js/aall.js
+/unionjs/$script
+/variety.tc.qq.com/*.mp4^*fmt=hd
+/variety.tc.qq.com/*.mp4^*fmt=shd
+/video.dispatch.tc.qq.com/*.mp4^*sdtfrom=
+/view/image/QT_HY.jpg?t=
+/view/js/slade.js|$script
+/vlive.qqvideo.tc.qq.com/*.mp4^*fmt=hd
+/vlive.qqvideo.tc.qq.com/*.mp4^*fmt=shd
+/vmind.qqvideo.tc.qq.com/*.mp4^*sdtfrom=
+/vmindhls.tc.qq.com/*ugc=0&ga=0&gv=0&start=
+/zzhzgg.js
\ No newline at end of file
diff --git a/adbyby/files/data/rules.txt b/adbyby/files/data/rules.txt
new file mode 100644
index 000000000..5c44b0e8c
--- /dev/null
+++ b/adbyby/files/data/rules.txt
@@ -0,0 +1,15 @@
+! ------------------------------ ADByby 自定义过滤语法简表---------------------------------
+! -------------- 规则基于abp规则,并进行了字符替换部分的扩展-----------------------------
+! ABP规则请参考https://adblockplus.org/zh_CN/filters,下面为大致摘要
+! "!" 为行注释符,注释行以该符号起始作为一行注释语义,用于规则描述
+! "*" 为字符通配符,能够匹配0长度或任意长度的字符串,该通配符不能与正则语法混用。
+! "^" 为分隔符,可以是除了字母、数字或者 _ - . % 之外的任何字符。
+! "|" 为管线符号,来表示地址的最前端或最末端
+! "||" 为子域通配符,方便匹配主域名下的所有子域。
+! "~" 为排除标识符,通配符能过滤大多数广告,但同时存在误杀, 可以通过排除标识符修正误杀链接。
+! "##" 为元素选择器标识符,后面跟需要隐藏元素的CSS样式例如 #ad_id .ad_class
+!! 元素隐藏暂不支持全局规则和排除规则
+!! 字符替换扩展
+! 文本替换选择器标识符,后面跟需要替换的文本数据,格式:$s@模式字符串@替换后的文本@
+! 支持通配符*和?
+! -------------------------------------------------------------------------------------------
diff --git a/adbyby/files/data/user.txt b/adbyby/files/data/user.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/adbyby/files/data/video.txt b/adbyby/files/data/video.txt
new file mode 100644
index 000000000..3991c48fc
--- /dev/null
+++ b/adbyby/files/data/video.txt
@@ -0,0 +1,30 @@
+! -----ʱ: 2018-10-08 23:06:11 by:xwhyc-----------------------------------------------
+! -----淴:http://www.adbyby.com/help.htm QQȺ: 79547134(), 364066294()470705224()534897434,438394572--------------
+
+
+!-------------------------------------------
+/showadv/
+3199.cn###ad640,[id^="ad0"]
+76fengyun.com###down_box{display:block!important;}.gggg,.ggao
+9553.com##[class="zm"]
+962.net##.show_ad,.g-962-ad
+amazon.cn##.adv-float-div
+downsx.rocks##.adbox,.Left-ad3_fixed,.google-ad2_fixed
+edu-acc.cn###doyoo_monitor
+fx678.com##[class^="adv-"]
+||76fengyun.com/body22233.js
+||76fengyun.com/file/$s@onclick="window.open('*');startWait();"@onclick="window.open(document.getElementById('downpage_link').href);startWait();"@
+||atanx.alicdn.com/t/tanxssp.js?_v=
+||biquguan.com/guan/$script
+||djv99sxoqpv11.cloudfront.net
+||jmxlaser.com
+||jump2.bdimg.com/p/$s@
+~,\s])\s*(\*|(?:[-\w*]|[^\x00-\xa0]|\\.)*)/,trimLeft=/^\s+/,trimRight=/\s+$/,reg_comma=/^\s*,\s*/,reg_sequence=/^([#\.:]|\[\s*)((?:[-\w]|[^\x00-\xa0]|\\.)+)/,reg_pseudo=/^\(\s*("([^"]*)"|'([^']*)'|[^\(\)]*(\([^\(\)]*\))?)\s*\)/,reg_attrib=/^\s*(?:(\S?=)\s*(?:(['"])(.*?)\2|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,reg_attrval=/\\([0-9a-fA-F]{2,2})/g,reg_sensitive=/^(?:title|id|name|class|for|href|src)$/,reg_backslash=/\\/g,reg_tag=/^((?:[-\w\*]|[^\x00-\xa0]|\\.)+)/,reg_parse_pseudo=/(-?)(\d*)n([-+]?\d*)/,reg_quick=/^(^|[#.])((?:[-\w]|[^\x00-\xa0]|\\.)+)$/,has_in=function(a,b){return(a in b)},dom={html:DOC.documentElement,mix:function(target,source){var args=[].slice.call(arguments),key,ride=typeof args[args.length-1]=="boolean"?args.pop():true;target=target||{};for(var i=1;source=args[i++];){for(key in source){if(ride||!has_in(key,target)){target[key]=source[key]}}}return target},rword:/[^, ]+/g,uuid:1,getUid:w3c_css?function(node){return node.uniqueNumber||(node.uniqueNumber=dom.uuid++)}:function(node){var uid=node.getAttribute("uniqueNumber");if(!uid){uid=dom.uuid++;node.setAttribute("uniqueNumber",uid)}return uid},oneObject:function(array,val){if(typeof array=="string"){array=array.match(dom.rword)||[]}var result={},value=val!==undef?val:1;for(var i=0,n=array.length;i
=0);(found^flag_not)&&(result[ri++]=el)}return result}}},onePosition=dom.oneObject("eq,gt,lt,first,last,even,odd"),siblingCheck=function(a,b,ret){if(a===b){return ret}var cur=a.nextSibling;while(cur){if(cur===b){return -1}cur=cur.nextSibling}return 1},sortOrder1=function(a,b){if(a===b){sortOrder1.hasDuplicate=true;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition){return a.compareDocumentPosition?-1:1}return a.compareDocumentPosition(b)&4?-1:1},sortOrder2=function(a,b){if(a===b){sortOrder2.hasDuplicate=true;return 0}var al,bl,ap=[],bp=[],aup=a.parentNode,bup=b.parentNode,cur=aup;if(aup===bup){return siblingCheck(a,b)}else{if(!aup){return -1}else{if(!bup){return 1}}}while(cur){ap.unshift(cur);cur=cur.parentNode}cur=bup;while(cur){bp.unshift(cur);cur=cur.parentNode}al=ap.length;bl=bp.length;for(var i=0;i0&&els.length&&els[0].lookupNamespaceURI){var arr=tagName.split(":");prefix=arr[0];tagName=arr[1];method="getElementsByTagNameNS";prefix=els[0].lookupNamespaceURI(prefix)}switch(els.length){case 0:return elems;case 1:var all=prefix?els[0][method](prefix,tagName):els[0][method](tagName);for(var i=0,ri=0,el;el=all[i++];){if(el.nodeType===1){elems[ri++]=el}}return elems;default:for(var nodes,i=0,ri=0;el=els[i++];){nodes=prefix?el[method](prefix,tagName):el[method](tagName);for(var uid,j=0,node;node=nodes[j++];){uid=dom.getUid(node);if(!uniqResult[uid]){uniqResult[uid]=elems[ri++]=node}}}return elems}},getElementsByXPath=function(xpath,context,doc){var result=[];try{if(global.DOMParser){var nodes=doc.evaluate(xpath,context,null,7,null);for(var i=0,n=nodes.snapshotLength;i";root.insertBefore(form,root.firstChild);fixById=!!DOC.getElementById(id);root.removeChild(form)})();try{slice.call(dom.html.childNodes,0)[0].nodeType}catch(e){makeArray=function(nodes,result,flag_multi){var ret=result||[],ri=ret.length;for(var i=0,el;el=nodes[i++];){ret[ri++]=el}return flag_multi?dom.unique(ret):ret}}var Icarus=dom.query=function(expr,contexts,result,lastResult,flag_xml,flag_multi,flag_dirty){result=result||[];contexts=contexts||DOC;var pushResult=makeArray;if(!contexts.nodeType){contexts=pushResult(contexts);if(!contexts.length){return result}}else{contexts=[contexts]}var rrelative=reg_combinator,rBackslash=reg_backslash,rcomma=reg_comma,context=contexts[0],doc=context.ownerDocument||context,rtag=reg_tag,flag_all,uniqResult,elems,nodes,tagName,last,ri,uid;expr=expr.replace(trimLeft,"").replace(trimRight,"");flag_xml=flag_xml!==undef?flag_xml:dom.isXML(doc);if(flag_xml&&expr==="body"&&context.body){return pushResult([context.body],result,flag_multi)}if(!flag_xml&&doc.querySelectorAll){var query=expr,fix_icarus_sqa="fix_icarus_sqa";if(contexts.length>2||doc.documentMode==8&&context.nodeType==1){if(contexts.length>2){context=doc}query="."+fix_icarus_sqa+" "+query;for(var i=0,node;node=contexts[i++];){if(node.nodeType===1){node.className=fix_icarus_sqa+" "+node.className}}}if(doc.documentMode!==8||context.nodeName.toLowerCase()!=="object"){try{return pushResult(context.querySelectorAll(query),result,flag_multi)}catch(e){}finally{if(!query.indexOf("."+fix_icarus_sqa)){for(i=0;node=contexts[i++];){if(node.nodeType===1){node.className=node.className.replace(fix_icarus_sqa+" ","")}}}}}}var match=expr.match(reg_quick);if(match){var value=match[2].replace(rBackslash,""),key=match[1];if(key==""){nodes=getElementsByTagName(value,contexts,flag_xml)}else{if(key==="."&&contexts.length===1){if(flag_xml){nodes=getElementsByXPath("//*[@class='"+value+"']",context,doc)}else{if(context.getElementsByClassName){nodes=context.getElementsByClassName(value)}}}else{if(key==="#"&&contexts.length===1){if(flag_xml){nodes=getElementsByXPath("//*[@id='"+value+"']",context,doc)}else{if(context.nodeType==Math.pow(3,2)){node=doc.getElementById(value);nodes=!node?[]:!fixById?[node]:node.getAttributeNode("id").nodeValue===value?[node]:false}}}}}if(nodes){return pushResult(nodes,result,flag_multi)}}lastResult=contexts;if(lastResult.length){loop:while(expr&&last!==expr){flag_dirty=false;elems=null;uniqResult={};if((match=expr.match(rrelative))){expr=RegExp.rightContext;elems=[];tagName=(flag_xml?match[2]:match[2].toUpperCase()).replace(rBackslash,"")||"*";i=0;ri=0;flag_all=tagName==="*";switch(match[1]){case" ":if(expr.length||match[2]){elems=getElementsByTagName(tagName,lastResult,flag_xml)}else{elems=lastResult;break loop}break;case">":while((node=lastResult[i++])){for(node=node.firstChild;node;node=node.nextSibling){if(node.nodeType===1&&(flag_all||tagName===node.nodeName)){elems[ri++]=node}}}break;case"+":while((node=lastResult[i++])){while((node=node.nextSibling)){if(node.nodeType===1){if(flag_all||tagName===node.nodeName){elems[ri++]=node}break}}}break;case"~":while((node=lastResult[i++])){while((node=node.nextSibling)){if(node.nodeType===1&&(flag_all||tagName===node.nodeName)){uid=dom.getUid(node);if(uniqResult[uid]){break}else{uniqResult[uid]=elems[ri++]=node}}}}elems=dom.unique(elems);break}}else{if((match=expr.match(rtag))){expr=RegExp.rightContext;elems=getElementsByTagName(match[1].replace(rBackslash,""),lastResult,flag_xml)}}if(expr){var arr=Icarus.filter(expr,elems,lastResult,doc,flag_xml);expr=arr[0];elems=arr[1];if(!elems){flag_dirty=true;elems=getElementsByTagName("*",lastResult,flag_xml)}if((match=expr.match(rcomma))){expr=RegExp.rightContext;pushResult(elems,result);return Icarus(expr,contexts,result,[],flag_xml,true,flag_dirty)}else{lastResult=elems}}}}if(flag_multi){if(elems.length){return pushResult(elems,result,flag_multi)}}else{if(DOC!==doc||fixByTag&&flag_dirty){for(result=[],ri=0,i=0;node=elems[i++];){if(node.nodeType===1){result[ri++]=node}}return result}}return elems},filterPseudoNoExp=function(name,isLast,isOnly){var A="for(var result=[],flag_not=A.not,node,el,tagName,i=0,ri=0,found=0;node=el=B[i++];found=0){",B="{0}while(!found&&(node=node.{1})){(node.{2}==={3})&&++found}",C="node=el;while(!found&&(node=node.previousSibling)){node.{2}==={3}&&++found}",D="!found^flag_not&&(result[ri++]=el)}return result",start=isLast?"nextSibling":"previousSibling",fills={type:["tagName=el.nodeName;",start,"nodeName","tagName"],child:["",start,"nodeType","1"]}[name],body=A+B+(isOnly?C:"")+D;return{exec:new Function("A","B",body.replace(/{(\d)}/g,function($,$1){return fills[$1]}))}};dom.mix(Icarus,{getAttribute:!fixGetAttribute?function(elem,name){return elem.getAttribute(name)||""}:function(elem,name,flag_xml){if(flag_xml){return elem.getAttribute(name)||""}name=name.toLowerCase();if(attrURL[name]){return elem.getAttribute(name,2)||""}if(elem.tagName==="INPUT"&&name=="type"){return elem.getAttribute("type")||elem.type}var attr=boolOne[name]?(elem.getAttribute(name)?name:""):(elem=elem.getAttributeNode(name))&&elem.value||"";return reg_sensitive.test(name)?attr:attr.toLowerCase()},hasAttribute:!fixHasAttribute?function(elem,name,flag_xml){return flag_xml?!!elem.getAttribute(name):elem.hasAttribute(name)}:function(elem,name){elem=elem.getAttributeNode(name.toLowerCase());return !!(elem&&(elem.specified||elem.nodeValue))},filter:function(expr,elems,lastResult,doc,flag_xml,flag_get){var rsequence=reg_sequence,rattrib=reg_attrib,rpseudo=reg_pseudo,rBackslash=reg_backslash,rattrval=reg_attrval,pushResult=makeArray,toHex=_toHex,_hash_op=hash_operator,parsePseudo=parse_pseudo,match,key,tmp;while((match=expr.match(rsequence))){expr=RegExp.rightContext;key=(match[2]||"").replace(rBackslash,"");if(!elems){if(lastResult.length===1&&lastResult[0]===doc){switch(match[1]){case"#":if(!flag_xml){tmp=doc.getElementById(key);if(!tmp){elems=[];continue}if(fixById?tmp.id===key:tmp.getAttributeNode("id").nodeValue===key){elems=[tmp];continue}}break;case":":switch(key){case"root":elems=[doc.documentElement];continue;case"link":elems=pushResult(doc.links||[]);continue}break}}elems=getElementsByTagName("*",lastResult,flag_xml)}var filter=0,flag_not=false,args;switch(match[1]){case"#":filter=["id","=",key];break;case".":filter=["class","~=",key];break;case":":tmp=Icarus.hook[key];if((match=expr.match(rpseudo))){expr=RegExp.rightContext;args=parsePseudo(key,match)}if(tmp){filter=tmp}else{if(key==="not"){flag_not=true;if(args==="*"){elems=[]}else{if(reg_tag.test(args)){tmp=[];match=flag_xml?args:args.toUpperCase();for(var i=0,ri=0,elem;elem=elems[i++];){if(match!==elem.nodeName){tmp[ri++]=elem}}elems=tmp}else{var obj=Icarus.filter(args,elems,lastResult,doc,flag_xml,true);filter=obj.filter;args=obj.args}}}else{throw"!"}}break;default:filter=[key.toLowerCase()];if((match=expr.match(rattrib))){expr=RegExp.rightContext;if(match[1]){filter[1]=match[1];filter[2]=match[3]||match[4];filter[2]=filter[2]?filter[2].replace(rattrval,toHex).replace(rBackslash,""):""}}break}if(flag_get){return{filter:filter,args:args}}if(elems.length&&filter){tmp=[];i=0;ri=0;if(typeof filter==="function"){if(onePosition[key]){args=args===undef?elems.length-1:~~args;for(;elem=elems[i];){if(filter(i++,args)^flag_not){tmp[ri++]=elem}}}else{while((elem=elems[i++])){if((!!filter(elem,args))^flag_not){tmp[ri++]=elem}}}}else{if(typeof filter.exec==="function"){tmp=filter.exec({not:flag_not,xml:flag_xml},elems,args,doc)}else{var name=filter[0],op=_hash_op[filter[1]],val=filter[2]||"",flag,attr,className;if(!flag_xml&&name==="class"&&op===4){val=" "+val+" ";while((elem=elems[i++])){className=elem.className;if(!!(className&&~(" "+className+" ").indexOf(val))^flag_not){tmp[ri++]=elem}}}else{if(!flag_xml&&op&&val&&!reg_sensitive.test(name)){val=val.toLowerCase()}if(op===4){val=" "+val+" "}while((elem=elems[i++])){if(!op){flag=Icarus.hasAttribute(elem,name,flag_xml)}else{if(val===""&&op>3){flag=false}else{attr=Icarus.getAttribute(elem,name,flag_xml);switch(op){case 1:(flag=attr===val);break;case 2:(flag=attr!==val);break;case 3:(flag=attr===val||attr.substr(0,val.length+1)===val+"-");break;case 4:(flag=attr!==""&&!!~(" "+attr+" ").indexOf(val));break;case 5:(flag=attr!==""&&!attr.indexOf(val));break;case 6:(flag=attr!==""&&attr.substr(attr.length-val.length)===val);break;case 7:(flag=attr!==""&&!!~attr.indexOf(val));break}}}if(flag^flag_not){tmp[ri++]=elem}}}}}elems=tmp}}return[expr,elems]}});Icarus.hook={root:function(el){return el===(el.ownerDocument||el.document).documentElement},"first-child":filterPseudoNoExp("child",false,false),"last-child":filterPseudoNoExp("child",true,false),"only-child":filterPseudoNoExp("child",true,true),"nth-child":filterPseudoHasExp("firstChild","nextSibling",false),link:{exec:function(flags,elems){var links=(elems[0].ownerDocument||elems[0].document).links;if(!links){return[]}var result=[],checked={},flag_not=flags.not;for(var i=0,ri=0,elem;elem=links[i++];){checked[dom.getUid(elem)]=1}for(i=0;elem=elems[i++];){if(checked[dom.getUid(elem)]^flag_not){result[ri++]=elem}}return result}},lang:{exec:function(flags,elems,arg){var result=[],reg=new RegExp("^"+arg,"i"),flag_not=flags.not;for(var tmp,i=0,ri=0,elem;elem=elems[i++];){tmp=elem;while(tmp&&!tmp.getAttribute("lang")){tmp=tmp.parentNode}tmp=!!(tmp&®.test(tmp.getAttribute("lang")));if(tmp^flag_not){result[ri++]=elem}}return result}},contains:{exec:function(flags,elems,arg){var res=[],flag_not=flags.not;for(var i=0,ri=0,elem;elem=elems[i++];){if(!!~((elem.innerText||elem.textContent||dom.getText([elem])).indexOf(arg))^flag_not){res[ri++]=elem}}return res}},selected:function(el){el.parentNode&&el.parentNode.selectedIndex;return el.selected===true},header:function(el){return/h\d/i.test(el.nodeName)},button:function(el){return"button"===el.type||el.nodeName==="BUTTON"},input:function(el){return/input|select|textarea|button/i.test(el.nodeName)},parent:function(el){return !!el.firstChild},has:function(el,expr){return !!dom.query(expr,[el]).length},first:function(index){return index===0},last:function(index,num){return index===num},even:function(index){return index%2===0},odd:function(index){return index%2===1},lt:function(index,num){return indexnum},eq:function(index,num){return index===num},hidden:function(el){return(el.offsetWidth+el.offsetHeight)==0||(el.currentStyle||{}).display=="none"}};Icarus.hook.visible=function(el){return !Icarus.hook.hidden(el)};"text,radio,checkbox,file,password,submit,image,reset".replace(dom.rword,function(name){Icarus.hook[name]=function(el){return(el.getAttribute("type")||el.type)===name}});var blockCss=/(?:function|open|document|location|alert|confirm|prompt|showmodelessdialog|activexobject|xmlhttprequest|execscript|eval)\s*[(.=;]/i,checkCss=function(a,b){b=b||"visibility";return"hidden"==(w3c_css?DOC.defaultView.getComputedStyle(a,null).getPropertyValue(b):a.currentStyle[b])},removeNode=!!global.VBArray?function(){var b;return function(a){if(a&&"BODY"!=a.tagName){b=b||DOC.createElement("DIV");b.appendChild(a);b.innerHTML=""}}}():function(a){a&&a.parentNode&&"BODY"!=a.tagName&&a.parentNode.removeChild(a)},execFunc=[function(){},function(a){for(var b,c=a.length;c--;){b=a[c];checkCss(b)||(b.style.display="none",b.style.visibility="hidden")}},function(a){for(var c=a.length;c--;){removeNode(a[c])}}],execMainFunc=function(a,b){var c;try{c=dom.query(a)}catch(e){return((c=null),0)}return("function"==typeof execFunc[b]&&execFunc[b](c),c.length)},const_DOMContentLoaded="DOMContentLoaded",const_complete="complete",domReadyList=[],domisReady=0,domReady=function(fn){domisReady?fn():domReadyList.unshift(fn)},domfireReady=function(){if(!domisReady){if(!DOC.body){return setTimeout(domfireReady,32)}domisReady=1;for(var len=domReadyList.length;len--;){domReadyList[len]()}}},createCss=(function(){var style,media,self={},reg_media=/screen|all/i,splitCss=/[\[+>~:].+?/,addCss="{display:none;position:absolute;top:-1000000px;visibility:hidden}",styles=DOC.getElementsByTagName("style"),len=styles.length,new_css=function(g){for(var r=[],z=[],o,y=g.split(","),E=y.length;E--;){o=y[E];o&&(splitCss.test(o)?r:z).push(o)}z.length&&r.push(z.join());return(r.join(addCss)||"iframe")+addCss};while(len--){style=styles[len];media=style.getAttribute("media");if(media===null||reg_media.test(media)){self.style=style;break}}if(!self.style){var head=DOC.head||DOC.getElementsByTagName("head")[0];style=DOC.createElement("style");head.insertBefore(style,head.firstChild);domReady(function(){DOC.body&&DOC.body.insertBefore(style,DOC.body.firstChild)})}return style.styleSheet?function(css){style.styleSheet.cssText+=new_css(css)}:!!global.Components?function(css){style.innerHTML+=new_css(css)}:function(css){style.appendChild(DOC.createTextNode(new_css(css)))}})();if(const_complete==DOC.readyState){domfireReady()}else{if(!DOC.attachEvent){DOC.addEventListener(const_DOMContentLoaded,function(){DOC.removeEventListener(const_DOMContentLoaded,arguments.callee,false);domfireReady()},false)}else{DOC.attachEvent("onreadystatechange",function(){const_complete==DOC.readyState&&(DOC.detachEvent("onreadystatechange",arguments.callee),domfireReady())});(function(){if(domisReady){return}try{var node=new Image();node.doScroll();node=null}catch(e){setTimeout(arguments.callee,64);return}domfireReady()})()}}var AdSafe_CheckRule={regIDS:null,regSub:null,format:function(){var str=arguments[0];var regM=/\{\s*(\d+)\s*\}/,arr,temp="",xb;while((arr=regM.exec(str))!=null){xb=parseInt(arr[1]);if(isNaN(xb)||typeof(arguments[xb+1])=="undefined"){throw"��ָ������:"+arr[0]}temp+=str.substr(0,arr.index)+arguments[xb+1];str=str.substr(arr.index+arr[0].length)}temp+=str;return temp},isNullOrEmpty:function(str){var t=str;if(str.constructor==Array){t=str[0]}if(t==null||t==""){return true}return false},trim:function(str,dir){var regTrim;if(dir=="left"){regTrim=/^\s*/g}else{if(dir=="right"){regTrim=/\s*$/g}else{regTrim=/(?:^\s*|\s*$)/g}}if(str.constructor==String){str=str.replace(regTrim,"")}else{if(str.constructor==Array){for(var i=0;i+]\\s*)?(?:{0}|{1}|{2})+)+",str_iden,str_attr,str_quick),str_jquerys=this.format("^{0}\\s*(?:,\\s*{0}\\s*)*$",str_alone);this.regIDS=new RegExp(str_jquerys,"i");this.regSub=new RegExp(strSub,"i")},Checking:function(str){if(this.isNullOrEmpty(str)){return false}var result=this.AloneSub(str);if(!result){return false}if(this.isNullOrEmpty(str)){return true}if(!this.CheckRules(str)){return false}return true},CheckRules:function(str){var strArr=str[0].split(",");var lst=[];for(var t=0;t0){return false}else{return true}},GetPair:function(k){var t=[],result=[],c;t.push("0");for(var i=0;i0){var rc=str[0].charAt(temp1.length-1);if(rc==">"||rc=="+"||rc==","){if(temp1.length-1>=0){temp1=temp1.substr(0,temp1.length-1)}hasSub=true}}if(hasSub){str[0]=temp1+" "+str[0].substr(m.index+m[0].length+temp[0].length+1)}else{str[0]=str[0].substr(0,m.index)+str[0].substr(m.index+m[0].length+temp[0].length+1)}str[0]=this.trim(str[0])}if(this.isNullOrEmpty(str)){return true}return this.AloneSub(str)}else{return this.CheckRules(str)}}};var isIni=false;var checkCSSRule=function(line){if(!isIni){AdSafe_CheckRule.ini();isIni=true}var i=line.indexOf("??1");if(i>=0){line=line.substr(0,i)}line=AdSafe_CheckRule.trim(line);if(line==""){return false}return AdSafe_CheckRule.Checking([line])};global.hidecss=function(c){if(c.indexOf("??1")>-1||c.indexOf("??")<0){try{if(!checkCSSRule(c)){return}}catch(e){}}if(!c||blockCss.test(c)){return}var d=String(c).split("??"),f=parseInt(d[1],10)||1,g=d[0],l=100;var setCookie=function(name,value,expires,path,domain,secure){var curCookie=name+"="+escape(value)+((expires)?"; expires="+expires.toGMTString():"")+((path)?"; path="+path:"")+((domain)?"; domain="+domain:"")+((secure)?"; secure":"");document.cookie=curCookie};var addCookieForHours=function(name,value,path,domain,hour,secure){var t;if(hour){t=new Date();hour=isNaN(parseFloat(hour))?1:hour;t.setTime(t.getTime()+hour*3600*1000)}setCookie(name,value,t,path,domain,secure)};var deleteCookie=function(name,path,domain){document.cookie=name+"="+((path)?"; path="+path:"")+((domain)?"; domain="+domain:"")+"; expires=Thu, 01-Jan-70 00:00:01 GMT"};var clearCookie=function(path,domain,arr){var keys=[],r,reg=/([^=; ]+)=([^;]+)/g,cook=document.cookie;while((r=reg.exec(cook))!=null){keys.push(r[1])}if(keys&&keys.length>0){var _f;if(typeof arr=="undefined"||!arr){arr=[]}if(typeof arr=="string"){arr=[arr]}for(var i=keys.length-1;i--;i>=0){_f=false;for(var k=0;k/dev/null") == 0
+ luci.http.prepare_content("application/json")
+ luci.http.write_json(e)
+end
+
+
+function refresh_data()
+ local set = luci.http.formvalue("set")
+ local icount = 0
+
+if set == "rule_data" then
+luci.sys.exec("/usr/share/adbyby/rule-update")
+ icount = luci.sys.exec("/usr/share/adbyby/rule-count '/tmp/rules/'")
+
+ if tonumber(icount)>0 then
+ if nixio.fs.access("/usr/share/adbyby/rules/") then
+ oldcount = luci.sys.exec("/usr/share/adbyby/rule-count '/usr/share/adbyby/rules/'")
+ else
+ oldcount=0
+ end
+ else
+ retstring ="-1"
+ end
+
+ if tonumber(icount) ~= tonumber(oldcount) then
+ luci.sys.exec("rm -f /usr/share/adbyby/rules/data/* /usr/share/adbyby/rules/host/* && cp -a /tmp/rules /usr/share/adbyby/")
+ luci.sys.exec("/etc/init.d/adbyby restart &")
+ retstring=tostring(math.ceil(tonumber(icount)))
+ else
+ retstring ="0"
+ end
+else
+refresh_cmd = "uclient-fetch -q --no-check-certificate -O - 'https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt' > /tmp/adnew.conf"
+sret = luci.sys.call(refresh_cmd .. " 2>/dev/null")
+if sret== 0 then
+ luci.sys.call("/usr/share/adbyby/ad-update")
+ icount = luci.sys.exec("cat /tmp/ad.conf | wc -l")
+ if tonumber(icount)>0 then
+ if nixio.fs.access("/usr/share/adbyby/dnsmasq.adblock") then
+ oldcount = luci.sys.exec("cat /usr/share/adbyby/dnsmasq.adblock | wc -l")
+ else
+ oldcount=0
+ end
+ if tonumber(icount) ~= tonumber(oldcount) then
+ luci.sys.exec("cp -f /tmp/ad.conf /usr/share/adbyby/dnsmasq.adblock")
+ luci.sys.exec("cp -f /tmp/ad.conf /tmp/etc/dnsmasq-adbyby.d/adblock")
+ luci.sys.exec("/etc/init.d/adbyby restart &")
+ retstring=tostring(math.ceil(tonumber(icount)))
+ else
+ retstring ="0"
+ end
+ else
+ retstring ="-1"
+ end
+ luci.sys.exec("rm -f /tmp/ad.conf")
+else
+ retstring ="-1"
+end
+end
+luci.http.prepare_content("application/json")
+luci.http.write_json({ ret=retstring ,retcount=icount})
+end
diff --git a/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/advanced.lua b/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/advanced.lua
new file mode 100644
index 000000000..1d9faa69a
--- /dev/null
+++ b/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/advanced.lua
@@ -0,0 +1,57 @@
+
+local SYS = require "luci.sys"
+local ND = SYS.exec("cat /usr/share/adbyby/dnsmasq.adblock | wc -l")
+
+local ad_count=0
+if nixio.fs.access("/usr/share/adbyby/dnsmasq.adblock") then
+ad_count=tonumber(SYS.exec("cat /usr/share/adbyby/dnsmasq.adblock | wc -l"))
+end
+
+local rule_count=0
+if nixio.fs.access("/usr/share/adbyby/rules/") then
+rule_count=tonumber(SYS.exec("/usr/share/adbyby/rule-count '/usr/share/adbyby/rules/'"))
+end
+
+m = Map("adbyby")
+
+s = m:section(TypedSection, "adbyby")
+s.anonymous = true
+
+o = s:option(Flag, "block_ios")
+o.title = translate("Block Apple iOS OTA update")
+o.default = 0
+o.rmempty = false
+
+o = s:option(Flag, "block_cnshort")
+o.title = translate("Block CNshort APP and Website")
+o.default = 0
+o.rmempty = false
+
+o = s:option(Flag, "cron_mode")
+o.title = translate("Update the rule at 6 a.m. every morning and restart adbyby")
+o.default = 0
+o.rmempty = false
+
+o=s:option(DummyValue,"ad_data",translate("Adblock Plus Data"))
+o.rawhtml = true
+o.template = "adbyby/refresh"
+o.value =ad_count .. " " .. translate("Records")
+
+o=s:option(DummyValue,"rule_data",translate("Subscribe 3rd Rules Data"))
+o.rawhtml = true
+o.template = "adbyby/refresh"
+o.value =rule_count .. " " .. translate("Records")
+o.description = translate("AdGuardHome / Host / DNSMASQ rules auto-convert")
+
+o = s:option(Button,"delete",translate("Delete All Subscribe Rules"))
+o.inputstyle = "reset"
+o.write = function()
+ SYS.exec("rm -f /usr/share/adbyby/rules/data/* /usr/share/adbyby/rules/host/*")
+ SYS.exec("/etc/init.d/adbyby restart 2>&1 &")
+ luci.http.redirect(luci.dispatcher.build_url("admin", "services", "adbyby", "advanced"))
+end
+
+o = s:option(DynamicList, "subscribe_url", translate("Anti-AD Rules Subscribe"))
+o.rmempty = true
+
+return m
diff --git a/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/base.lua b/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/base.lua
new file mode 100644
index 000000000..b9872cb19
--- /dev/null
+++ b/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/base.lua
@@ -0,0 +1,66 @@
+local NXFS = require "nixio.fs"
+local SYS = require "luci.sys"
+local HTTP = require "luci.http"
+local DISP = require "luci.dispatcher"
+
+local DL = SYS.exec("head -1 /tmp/adbyby/data/lazy.txt | awk -F' ' '{print $3,$4}'") or ""
+local DV = SYS.exec("head -1 /tmp/adbyby/data/video.txt | awk -F' ' '{print $3,$4}'") or ""
+local NR = SYS.exec("grep -v '^!' /usr/share/adbyby/data/rules.txt | wc -l")
+local NU = SYS.exec("cat /usr/share/adbyby/data/user.txt | wc -l")
+local UD = NXFS.readfile("/tmp/adbyby.updated") or "1970-01-01 00:00:00"
+
+m = Map("adbyby")
+m.title = translate("Adbyby Plus + Settings")
+m.description = translate("Adbyby Plus + can filter all kinds of banners, popups, video ads, and prevent tracking, privacy theft and a variety of malicious websites
Plus + version combination mode can operation with Adblock Plus Host,filtering ads without losing bandwidth")
+
+m:section(SimpleSection).template = "adbyby/adbyby_status"
+
+s = m:section(TypedSection, "adbyby")
+s.anonymous = true
+
+o = s:option(Flag, "enable", translate("Enable"))
+o.default = 0
+o.rmempty = false
+
+o = s:option(ListValue, "wan_mode", translate("Running Mode"))
+o:value("0", translate("Global Mode (The slowest and the best effects)"))
+o:value("1", translate("Plus + Mode (Filter domain name list and blacklist website.Recommended)"))
+o:value("2", translate("No filter Mode (Must set in Client Filter Mode Settings manually)"))
+o.default = 1
+o.rmempty = false
+
+o = s:option(Button, "restart", translate("Adbyby and Rule state"))
+o.inputtitle = translate("Update Adbyby Rules Manually")
+o.description = string.format(""..translate("Last Update Checked")..": %s
"..translate("Lazy Rule")..":%s
"..translate("Video Rule")..":%s", UD, DL, DV)
+o.inputstyle = "reload"
+o.write = function()
+ SYS.call("rm -rf /tmp/adbyby.updated /tmp/adbyby/admd5.json && /usr/share/adbyby/adbybyupdate.sh > /tmp/adupdate.log 2>&1 &")
+ SYS.call("sleep 5")
+ HTTP.redirect(DISP.build_url("admin", "services", "adbyby"))
+end
+
+t = m:section(TypedSection, "acl_rule", translate("Client Filter Mode Settings"))
+t.description = translate("Filter mode settings can be set to specific LAN clients ( No filter , Global filter ) . Does not need to be set by default.")
+t.template = "cbi/tblsection"
+t.sortable = true
+t.anonymous = true
+t.addremove = true
+
+e = t:option(Value, "ipaddr", translate("IP Address"))
+e.width = "40%"
+e.datatype = "ip4addr"
+e.placeholder = "0.0.0.0/0"
+luci.ip.neighbors({ family = 4 }, function(entry)
+ if entry.reachable then
+ e:value(entry.dest:string())
+ end
+end)
+
+e = t:option(ListValue, "filter_mode", translate("Filter Mode"))
+e.width = "40%"
+e.default = "disable"
+e.rmempty = false
+e:value("disable", translate("No filter"))
+e:value("global", translate("Global filter"))
+
+return m
diff --git a/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/black.lua b/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/black.lua
new file mode 100644
index 000000000..3fd32ec4e
--- /dev/null
+++ b/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/black.lua
@@ -0,0 +1,23 @@
+local fs = require "nixio.fs"
+local conffile = "/usr/share/adbyby/adblack.conf"
+
+f = SimpleForm("custom")
+
+t = f:field(TextValue, "conf")
+t.rmempty = true
+t.rows = 13
+function t.cfgvalue()
+ return fs.readfile(conffile) or ""
+end
+
+function f.handle(self, state, data)
+ if state == FORM_VALID then
+ if data.conf then
+ fs.writefile(conffile, data.conf:gsub("\r\n", "\n"))
+ luci.sys.call("/etc/init.d/adbyby restart")
+ end
+ end
+ return true
+end
+
+return f
diff --git a/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/block.lua b/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/block.lua
new file mode 100644
index 000000000..dd715fd88
--- /dev/null
+++ b/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/block.lua
@@ -0,0 +1,23 @@
+local fs = require "nixio.fs"
+local conffile = "/usr/share/adbyby/blockip.conf"
+
+f = SimpleForm("custom")
+
+t = f:field(TextValue, "conf")
+t.rmempty = true
+t.rows = 13
+function t.cfgvalue()
+ return fs.readfile(conffile) or ""
+end
+
+function f.handle(self, state, data)
+ if state == FORM_VALID then
+ if data.conf then
+ fs.writefile(conffile, data.conf:gsub("\r\n", "\n"))
+ luci.sys.call("/etc/init.d/adbyby restart")
+ end
+ end
+ return true
+end
+
+return f
diff --git a/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/esc.lua b/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/esc.lua
new file mode 100644
index 000000000..5c6f168a1
--- /dev/null
+++ b/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/esc.lua
@@ -0,0 +1,23 @@
+local fs = require "nixio.fs"
+local conffile = "/usr/share/adbyby/adesc.conf"
+
+f = SimpleForm("custom")
+
+t = f:field(TextValue, "conf")
+t.rmempty = true
+t.rows = 13
+function t.cfgvalue()
+ return fs.readfile(conffile) or ""
+end
+
+function f.handle(self, state, data)
+ if state == FORM_VALID then
+ if data.conf then
+ fs.writefile(conffile, data.conf:gsub("\r\n", "\n"))
+ luci.sys.call("/etc/init.d/adbyby restart")
+ end
+ end
+ return true
+end
+
+return f
diff --git a/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/help.lua b/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/help.lua
new file mode 100644
index 000000000..a0c20b90d
--- /dev/null
+++ b/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/help.lua
@@ -0,0 +1,23 @@
+local fs = require "nixio.fs"
+local conffile = "/usr/share/adbyby/adhost.conf"
+
+f = SimpleForm("custom")
+
+t = f:field(TextValue, "conf")
+t.rmempty = true
+t.rows = 13
+function t.cfgvalue()
+ return fs.readfile(conffile) or ""
+end
+
+function f.handle(self, state, data)
+ if state == FORM_VALID then
+ if data.conf then
+ fs.writefile(conffile, data.conf:gsub("\r\n", "\n"))
+ luci.sys.call("/etc/init.d/adbyby restart")
+ end
+ end
+ return true
+end
+
+return f
diff --git a/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/user.lua b/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/user.lua
new file mode 100644
index 000000000..13887db99
--- /dev/null
+++ b/luci-app-adbyby-plus/luasrc/model/cbi/adbyby/user.lua
@@ -0,0 +1,23 @@
+local fs = require "nixio.fs"
+local conffile = "/usr/share/adbyby/rules.txt"
+
+f = SimpleForm("custom")
+
+t = f:field(TextValue, "conf")
+t.rmempty = true
+t.rows = 13
+function t.cfgvalue()
+ return fs.readfile(conffile) or ""
+end
+
+function f.handle(self, state, data)
+ if state == FORM_VALID then
+ if data.conf then
+ fs.writefile(conffile, data.conf:gsub("\r\n", "\n"))
+ luci.sys.call("/etc/init.d/adbyby restart")
+ end
+ end
+ return true
+end
+
+return f
diff --git a/luci-app-adbyby-plus/luasrc/view/adbyby/adbyby_status.htm b/luci-app-adbyby-plus/luasrc/view/adbyby/adbyby_status.htm
new file mode 100644
index 000000000..3b2f40e06
--- /dev/null
+++ b/luci-app-adbyby-plus/luasrc/view/adbyby/adbyby_status.htm
@@ -0,0 +1,22 @@
+
+
+
diff --git a/luci-app-adbyby-plus/luasrc/view/adbyby/refresh.htm b/luci-app-adbyby-plus/luasrc/view/adbyby/refresh.htm
new file mode 100644
index 000000000..5c0285bcd
--- /dev/null
+++ b/luci-app-adbyby-plus/luasrc/view/adbyby/refresh.htm
@@ -0,0 +1,35 @@
+<%+cbi/valueheader%>
+
+
+<%=self.value%>
+<%+cbi/valuefooter%>
diff --git a/luci-app-adbyby-plus/po/zh-cn/adbyby.po b/luci-app-adbyby-plus/po/zh-cn/adbyby.po
new file mode 100644
index 000000000..f82a0b38c
--- /dev/null
+++ b/luci-app-adbyby-plus/po/zh-cn/adbyby.po
@@ -0,0 +1,198 @@
+msgid ""
+msgstr ""
+"Project-Id-Version: \n"
+"POT-Creation-Date: \n"
+"PO-Revision-Date: \n"
+"Last-Translator: dingpengyu \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: zh_CN\n"
+"X-Generator: Poedit 2.3.1\n"
+
+msgid "ADBYBY Plus +"
+msgstr "广告屏蔽大师 Plus+"
+
+msgid "Adbyby Plus + is Running"
+msgstr "广告屏蔽大师 Plus + 正在运行"
+
+msgid "Adbyby Plus + is Not Running"
+msgstr "广告屏蔽大师 Plus + 没有运行"
+
+msgid "Adbyby Plus + can filter all kinds of banners, popups, video ads, and prevent tracking, privacy theft and a variety of malicious websites
Plus + version combination mode can operation with Adblock Plus Host,filtering ads without losing bandwidth"
+msgstr "广告屏蔽大师 Plus + 可以全面过滤各种横幅、弹窗、视频广告,同时阻止跟踪、隐私窃取及各种恶意网站
Plus + 版本可以和 Adblock Plus Host 结合方式运行,过滤广告不损失带宽"
+
+msgid "Adbyby Plus +"
+msgstr "广告屏蔽大师 Plus+"
+
+msgid "Adbyby Plus + Settings"
+msgstr "广告屏蔽大师 Plus+(支持 AdGuardHome /Host / DNSMASQ 规则)"
+
+msgid "Base Setting"
+msgstr "基本设置"
+
+msgid "Running Mode"
+msgstr "运行模式"
+
+msgid "Global Mode (The slowest and the best effects)"
+msgstr "全局模式(最慢, 效果最好)"
+
+msgid "Plus + Mode (Filter domain name list and blacklist website.Recommended)"
+msgstr "Plus + 模式(只过滤列表内域名结合ABP名单。推荐!)"
+
+msgid "No filter Mode (Must set in Client Filter Mode Settings manually)"
+msgstr "手动代理模式(必须手动设置浏览器代理,或者客户端过滤模式设置)"
+
+msgid "Transparent proxy"
+msgstr "透明代理"
+
+msgid "Click to disable"
+msgstr "点击关闭"
+
+msgid "Click to enable"
+msgstr "点击开启"
+
+msgid "Adbyby and Rule state"
+msgstr "规则状态"
+
+msgid "Restart Adbyby"
+msgstr "重启Adbyby"
+
+msgid "Plus+ Domain List"
+msgstr "Plus+ 模式过滤的域名"
+
+msgid "Bypass Domain List"
+msgstr "域名白名单"
+
+msgid "Black Domain List"
+msgstr "域名黑名单"
+
+msgid "Black IP List"
+msgstr "IP黑名单"
+
+msgid "Advance Setting"
+msgstr "高级设置"
+
+msgid "Update the rule at 6 a.m. every morning and restart adbyby"
+msgstr "每天凌晨6点更新规则并重启"
+
+msgid "ADP Host List"
+msgstr "Adblock Plus Hosts 记录数"
+
+msgid "Adblock Plus Data"
+msgstr "Adblock Plus 规则数据库"
+
+msgid "Subscribe 3rd Rules Data"
+msgstr "订阅第三方去广告规则"
+
+msgid "Records"
+msgstr "条记录"
+
+msgid "Refresh Data"
+msgstr "更新数据库"
+
+msgid "Refresh..."
+msgstr "正在更新,请稍候.."
+
+msgid "Refresh OK!"
+msgstr "更新成功!"
+
+msgid "Refresh Error!"
+msgstr "更新失败!"
+
+msgid "No new data!"
+msgstr "你已经是最新数据,无需更新!"
+
+msgid "Total Records:"
+msgstr "新的总纪录数:"
+
+msgid "Delete All Subscribe Rules"
+msgstr "清空所有订阅的规则库"
+
+msgid "Anti-AD Rules Subscribe"
+msgstr "广告过滤规则订阅URL"
+
+msgid "AdGuardHome / Host / DNSMASQ rules auto-convert"
+msgstr "AdGuardHome / Host / DNSMASQ 规则自动识别"
+
+msgid "Manually force update
Adblock Plus Host List"
+msgstr "手动强制更新
Adblock Plus Host List"
+
+msgid "Update Adbyby Rules Manually"
+msgstr "手动更新规则"
+
+msgid "Block Apple iOS OTA update"
+msgstr "拦截 Apple iOS 的OTA更新"
+
+msgid "Block CNshort APP and Website"
+msgstr "拦截 短视频 APP 和网站"
+
+msgid "RAM Running Mode"
+msgstr "内存运行模式"
+
+msgid "Running Adbyby in RAM.More speed,less disk consumption"
+msgstr "在内存中运行Adbyby。更快的速度,更少的存储空间损耗"
+
+msgid "User-defined Rule"
+msgstr "用户自定义规则"
+
+msgid "Client Filter Mode Settings"
+msgstr "客户端过滤模式设置"
+
+msgid "Filter mode settings can be set to specific LAN clients ( No filter , Global filter ) . Does not need to be set by default."
+msgstr "可以为局域网客户端分别设置不同的过滤模式 ( 不过滤 , 全局过滤 ) 。默认无需设置。"
+
+msgid "IP Address"
+msgstr "IP地址"
+
+msgid "Filter Mode"
+msgstr "过滤模式"
+
+msgid "(!)Note that you should fill to the domain name ONLY. For example, http://www.baidu.com only needs to write to baidu.com. One line for each"
+msgstr "这些域名在 Plus 模式中会被过滤。你需要要填写域名即可,例如 http://www.baidu.com,你写 baidu.com 即可。每行一个域名"
+
+msgid "(!)Will Never filter these Domain"
+msgstr "永不过滤白名单内的域名(所有模式中生效)"
+
+msgid "(!)Will Always block these Domain"
+msgstr "拦截黑名单内的域名(所有模式中生效)"
+
+msgid "(!)Will Always block these IP"
+msgstr "拦截黑名单内的IP地址(所有模式中生效)"
+
+msgid "Each line of the beginning exclamation mark is considered an annotation."
+msgstr "每行一条规则,感叹号开头的被认为是注释。"
+
+msgid "Adblock Plus Host List:"
+msgstr "Adblock Plus Host 列表:"
+
+msgid "Note: It needs to download and convert the rules. The background process may takes 60-120 seconds to run.
After completed it would automatically refresh, please do not duplicate click!"
+msgstr "注意:需要下载并转换规则。后台进程可能需要60-120秒运行。完成后会自动刷新,请不要重复点击!"
+
+msgid "No filter"
+msgstr "不过滤"
+
+msgid "Global filter"
+msgstr "全局过滤"
+
+msgid "Update adbyby rules form official website first"
+msgstr "优先从官方网站更新规则"
+
+msgid "Last Update Checked"
+msgstr "上一次检查规则更新"
+
+msgid "Lazy Rule"
+msgstr "正式版规则"
+
+msgid "Video Rule"
+msgstr "测试版规则"
+
+msgid "Adblock Plus Host List"
+msgstr "广告屏蔽大师 Plus 规则列表"
+
+msgid "Block Domain List"
+msgstr "域名黑名单"
+
+msgid "Block IP List"
+msgstr "IP黑名单"
diff --git a/luci-app-adbyby-plus/root/etc/config/adbyby b/luci-app-adbyby-plus/root/etc/config/adbyby
new file mode 100644
index 000000000..d2afc6ed7
--- /dev/null
+++ b/luci-app-adbyby-plus/root/etc/config/adbyby
@@ -0,0 +1,11 @@
+
+config adbyby
+ option daemon '2'
+ option lan_mode '0'
+ option cron_mode '1'
+ option block_ios '0'
+ option enable '0'
+ option wan_mode '1'
+ option mem_mode '1'
+ option update_source '1'
+
diff --git a/luci-app-adbyby-plus/root/etc/init.d/adbyby b/luci-app-adbyby-plus/root/etc/init.d/adbyby
new file mode 100755
index 000000000..7fe29caba
--- /dev/null
+++ b/luci-app-adbyby-plus/root/etc/init.d/adbyby
@@ -0,0 +1,254 @@
+#!/bin/sh /etc/rc.common
+
+START=96
+STOP=10
+
+
+EXTRA_COMMANDS="add_rule del_rule reload_rule"
+PROG_PATH=/usr/share/adbyby
+DATA_PATH=$PROG_PATH/data
+WAN_FILE=/var/etc/dnsmasq-adbyby.d/03-adbyby-ipset.conf
+CRON_FILE=/etc/crontabs/root
+CONFIG=adbyby
+ipt_n="iptables -t nat"
+
+uci_get_by_name() {
+ local ret=$(uci get $CONFIG.$1.$2 2>/dev/null)
+ echo ${ret:=$3}
+}
+
+uci_get_by_type() {
+ local index=0
+ if [ -n $4 ]; then
+
+ index=$4
+ fi
+ local ret=$(uci get $CONFIG.@$1[$index].$2 2>/dev/null)
+ echo ${ret:=$3}
+}
+
+get_config()
+{
+ config_get_bool enable $1 enable 0
+ config_get_bool cron_mode $1 cron_mode 1
+ config_get wan_mode $1 wan_mode 1
+ config_get_bool block_ios $1 block_ios 0
+ config_get_bool mem_mode $1 mem_mode 1
+ config_get_bool block_cnshort $1 block_cnshort 0
+}
+
+add_rules()
+{
+ rm -f $DATA_PATH/user.bin
+ grep -v ^! $PROG_PATH/rules.txt > $DATA_PATH/user.txt
+ cp $PROG_PATH/rules.txt $DATA_PATH/rules.txt
+}
+
+
+add_cron()
+{
+ if [ $cron_mode -eq 1 ]; then
+ sed -i '/adblock.sh/d' $CRON_FILE
+ echo '0 6 * * * /usr/share/adbyby/adblock.sh > /tmp/adupdate.log 2>&1' >> $CRON_FILE
+ crontab $CRON_FILE
+ fi
+}
+
+del_cron()
+{
+ sed -i '/adblock.sh/d' $CRON_FILE
+ /etc/init.d/cron restart
+}
+
+ip_rule()
+{
+
+ ipset -N adbyby_esc hash:ip
+ $ipt_n -A ADBYBY -m set --match-set adbyby_esc dst -j RETURN
+
+ local icount=$(uci show adbyby | grep 'filter_mode' | wc -l)
+ let icount=icount-1
+ for i in $(seq 0 $icount)
+ do
+ local ip=$(uci_get_by_type acl_rule ipaddr '' $i)
+ local mode=$(uci_get_by_type acl_rule filter_mode '' $i)
+ case "$mode" in
+ disable)
+ $ipt_n -A ADBYBY -s $ip -j RETURN
+ ;;
+ global)
+ $ipt_n -A ADBYBY -s $ip -p tcp -j REDIRECT --to-ports 8118
+ $ipt_n -A ADBYBY -s $ip -j RETURN
+ ;;
+ esac
+ done
+
+
+
+ case $wan_mode in
+ 0)
+ ;;
+ 1)
+ ipset -N adbyby_wan hash:ip
+ $ipt_n -A ADBYBY -m set ! --match-set adbyby_wan dst -j RETURN
+ ;;
+ 2)
+ $ipt_n -A ADBYBY -j RETURN
+ ;;
+ esac
+
+ echo "create blockip hash:net family inet hashsize 1024 maxelem 65536" > /tmp/blockip.ipset
+ awk '!/^$/&&!/^#/{printf("add blockip %s'" "'\n",$0)}' /usr/share/adbyby/blockip.conf >> /tmp/blockip.ipset
+ ipset -! restore < /tmp/blockip.ipset 2>/dev/null
+ iptables -I FORWARD -m set --match-set blockip dst -j DROP
+ iptables -I OUTPUT -m set --match-set blockip dst -j DROP
+}
+
+add_dns()
+{
+ mkdir -p /var/etc/dnsmasq-adbyby.d
+ mkdir -p /tmp/dnsmasq.d
+
+ awk '!/^$/&&!/^#/{printf("ipset=/%s/'"adbyby_esc"'\n",$0)}' $PROG_PATH/adesc.conf > /var/etc/dnsmasq-adbyby.d/06-dnsmasq.esc
+ awk '!/^$/&&!/^#/{printf("address=/%s/'"0.0.0.0"'\n",$0)}' $PROG_PATH/adblack.conf > /var/etc/dnsmasq-adbyby.d/07-dnsmasq.black
+
+ echo 'conf-dir=/var/etc/dnsmasq-adbyby.d' > /tmp/dnsmasq.d/dnsmasq-adbyby.conf
+
+ local var=1
+ if [ $wan_mode -eq 1 ]; then
+ awk '!/^$/&&!/^#/{printf("ipset=/%s/'"adbyby_wan"'\n",$0)}' $PROG_PATH/adhost.conf > $WAN_FILE
+ if ls /var/etc/dnsmasq-adbyby.d/* >/dev/null 2>&1; then
+ mkdir -p /tmp/dnsmasq.d
+ cp /usr/share/adbyby/dnsmasq.adblock /var/etc/dnsmasq-adbyby.d/04-dnsmasq.adblock
+ cp /usr/share/adbyby/dnsmasq.ads /var/etc/dnsmasq-adbyby.d/05-dnsmasq.ads
+ fi
+ fi
+
+ mkdir -p /tmp/adbyby/rules/data /tmp/adbyby/rules/host
+ rm -f /tmp/adbyby/rules/data/* /tmp/adbyby/rules/host/*
+ cp -a /usr/share/adbyby/rules/data/* /tmp/adbyby/rules/data 2>/dev/null
+ cp -a /usr/share/adbyby/rules/host/* /tmp/adbyby/rules/host 2>/dev/null
+ echo 'addn-hosts=/tmp/adbyby/rules/host/' >> /tmp/dnsmasq.d/dnsmasq-adbyby.conf
+ echo 'conf-dir=/tmp/adbyby/rules/data' >> /tmp/dnsmasq.d/dnsmasq-adbyby.conf
+
+ [ $block_ios -eq 1 ] && echo 'address=/mesu.apple.com/0.0.0.0' >> /tmp/dnsmasq.d/dnsmasq-adbyby.conf
+ if [ $block_cnshort -eq 1 ]; then
+ cat <<-EOF >/tmp/etc/dnsmasq-adbyby.d/08-dnsmasq.cnshort
+address=/api.amemv.com/0.0.0.0
+address=/.amemv.com/0.0.0.0
+address=/.tiktokv.com/0.0.0.0
+address=/.snssdk.com/0.0.0.0
+address=/.douyin.com/0.0.0.0
+address=/.ixigua.com/0.0.0.0
+address=/.pstatp.com/0.0.0.0
+address=/.ixiguavideo.com/0.0.0.0
+address=/.v.kandian.qq.com/0.0.0.0
+address=/.yximgs.com/0.0.0.0
+address=/.gifshow.com/0.0.0.0
+address=/.ksapisrv.com/0.0.0.0
+address=/.kuaishoupay.com/0.0.0.0
+address=/.ksyun.com/0.0.0.0
+address=/.live.xycdn.com/0.0.0.0
+address=/.danuoyi.alicdn.com/0.0.0.0
+address=/.v.weishi.qq.com/0.0.0.0
+address=/.pearvideo.com/0.0.0.0
+address=/.miaopai.com/0.0.0.0
+address=/.kuaishou.com/0.0.0.0
+address=/.qupai.me/0.0.0.0
+address=/.meipai.com/0.0.0.0
+address=/.huoshan.com/0.0.0.0
+address=/.ergengtv.com/0.0.0.0
+address=/.baijiahao.baidu.com/0.0.0.0
+address=/.xiongzhang.baidu.com/0.0.0.0
+ EOF
+ fi
+}
+
+del_dns()
+{
+ rm -f /tmp/dnsmasq.d/dnsmasq-adbyby.conf
+ rm -f /var/etc/dnsmasq-adbyby.d/*
+ rm -f /tmp/adbyby_host.conf
+}
+
+
+add_rule()
+{
+ $ipt_n -N ADBYBY
+ $ipt_n -A ADBYBY -d 0.0.0.0/8 -j RETURN
+ $ipt_n -A ADBYBY -d 10.0.0.0/8 -j RETURN
+ $ipt_n -A ADBYBY -d 127.0.0.0/8 -j RETURN
+ $ipt_n -A ADBYBY -d 169.254.0.0/16 -j RETURN
+ $ipt_n -A ADBYBY -d 172.16.0.0/12 -j RETURN
+ $ipt_n -A ADBYBY -d 192.168.0.0/16 -j RETURN
+ $ipt_n -A ADBYBY -d 224.0.0.0/4 -j RETURN
+ $ipt_n -A ADBYBY -d 240.0.0.0/4 -j RETURN
+ ip_rule
+ if [ $(ipset list music -name -quiet | grep music) ]; then
+ $ipt_n -A ADBYBY -m set --match-set music dst -j RETURN 2>/dev/null
+ fi
+ $ipt_n -A ADBYBY -p tcp -j REDIRECT --to-ports 8118 2>/dev/null
+ $ipt_n -I PREROUTING -p tcp --dport 80 -j ADBYBY 2>/dev/null
+
+ mkdir -p /var/etc
+ echo -e "/etc/init.d/adbyby restart" > "/var/etc/adbyby.include"
+}
+
+del_rule()
+{
+ $ipt_n -D PREROUTING -p tcp --dport 80 -j ADBYBY 2>/dev/null
+ $ipt_n -F ADBYBY 2>/dev/null
+ $ipt_n -X ADBYBY 2>/dev/null
+ iptables -D FORWARD -m set --match-set blockip dst -j DROP 2>/dev/null
+ iptables -D OUTPUT -m set --match-set blockip dst -j DROP 2>/dev/null
+ ipset -F adbyby_esc 2>/dev/null
+ ipset -X adbyby_esc 2>/dev/null
+ ipset -F adbyby_wan 2>/dev/null
+ ipset -X adbyby_wan 2>/dev/null
+ ipset -F blockip 2>/dev/null
+ ipset -X blockip 2>/dev/null
+}
+
+reload_rule()
+{
+ config_load adbyby
+ config_foreach get_config adbyby
+ del_rule
+ [ $enable -eq 0 ] && exit 0
+ add_rule
+}
+
+start()
+{
+ config_load adbyby
+ config_foreach get_config adbyby
+
+ if [ $enable -ne 0 ]; then
+ add_cron
+ [ ! -d "/tmp/adbyby/data" ] && cp -a /usr/share/adbyby /tmp/ && rm -f /tmp/adbyby.updated
+ add_rules
+
+ /tmp/adbyby/adbyby >/dev/null 2>&1 &
+
+ add_dns
+ add_rule
+ /etc/init.d/dnsmasq restart
+ fi
+}
+
+stop()
+{
+ kill -9 $(busybox ps -w | grep "/tmp/adbyby/adbyby" | grep -v grep | grep -v update| grep -v adblock | awk '{print $1}') >/dev/null 2>&1
+ config_load adbyby
+ config_foreach get_config adbyby
+ del_rule
+ del_cron
+ del_dns
+ /etc/init.d/dnsmasq restart
+}
+
+boot()
+{
+ mkdir -p /tmp/adbyby && cp -a /usr/share/adbyby /tmp/
+ start
+}
diff --git a/luci-app-adbyby-plus/root/etc/uci-defaults/luci-adbyby b/luci-app-adbyby-plus/root/etc/uci-defaults/luci-adbyby
new file mode 100755
index 000000000..33cfa4787
--- /dev/null
+++ b/luci-app-adbyby-plus/root/etc/uci-defaults/luci-adbyby
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+uci -q batch <<-EOF >/dev/null
+ delete ucitrack.@adbyby[-1]
+ add ucitrack adbyby
+ set ucitrack.@adbyby[-1].init=adbyby
+ commit ucitrack
+ delete firewall.adbyby
+ set firewall.adbyby=include
+ set firewall.adbyby.type=script
+ set firewall.adbyby.path=/var/etc/adbyby.include
+ set firewall.adbyby.reload=1
+ delete firewall.adblock
+ add firewall rule
+ rename firewall.@rule[-1]="adblock"
+ set firewall.@rule[-1].name="adblock"
+ set firewall.@rule[-1].target="DROP"
+ set firewall.@rule[-1].src="wan"
+ set firewall.@rule[-1].proto="tcp"
+ set firewall.@rule[-1].dest_port="8118"
+ commit firewall
+EOF
+
+mkdir -p /etc/dnsmasq.d
+
+/etc/init.d/adbyby stop
+/etc/init.d/adbyby enable
+
+rm -f /tmp/luci-indexcache
+exit 0
diff --git a/luci-app-adbyby-plus/root/lib/upgrade/keep.d/adbyby b/luci-app-adbyby-plus/root/lib/upgrade/keep.d/adbyby
new file mode 100644
index 000000000..49b3eaafd
--- /dev/null
+++ b/luci-app-adbyby-plus/root/lib/upgrade/keep.d/adbyby
@@ -0,0 +1,6 @@
+/usr/share/adbyby/adhost.conf
+/usr/share/adbyby/adblack.conf
+/usr/share/adbyby/blockip.conf
+/usr/share/adbyby/adesc.conf
+/usr/share/adbyby/rules.txt
+/usr/share/adbyby/dnsmasq.adblock
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/ad-update b/luci-app-adbyby-plus/root/usr/share/adbyby/ad-update
new file mode 100755
index 000000000..77b43438f
--- /dev/null
+++ b/luci-app-adbyby-plus/root/usr/share/adbyby/ad-update
@@ -0,0 +1,11 @@
+#!/bin/sh -e
+if [ -f /tmp/adnew.conf ]; then
+ if (grep -wq "address=" /tmp/adnew.conf) ; then
+ cp /tmp/adnew.conf /tmp/ad.conf
+ elif (grep -wq "0.0.0.0" /tmp/adnew.conf) ; then
+ cp /tmp/adnew.conf /tmp/ad.conf
+ else
+ cat /tmp/adnew.conf | grep ^\|\|[^\*]*\^$ | sed -e 's:||:address\=\/:' -e 's:\^:/0\.0\.0\.0:' > /tmp/ad.conf
+ fi
+fi
+rm -f /tmp/adnew.conf
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/adblack.conf b/luci-app-adbyby-plus/root/usr/share/adbyby/adblack.conf
new file mode 100644
index 000000000..a532f5825
--- /dev/null
+++ b/luci-app-adbyby-plus/root/usr/share/adbyby/adblack.conf
@@ -0,0 +1,14 @@
+gvod.aiseejapp.atianqi.com
+stat.pandora.xiaomi.com
+upgrade.mishop.pandora.xiaomi.com
+logonext.tv.kuyun.com
+config.kuyun.com
+mishop.pandora.xiaomi.com
+dvb.pandora.xiaomi.com
+api.ad.xiaomi.com
+de.pandora.xiaomi.com
+data.mistat.xiaomi.com
+jellyfish.pandora.xiaomi.com
+gallery.pandora.xiaomi.com
+o2o.api.xiaomi.com
+bss.pandora.xiaomi.com
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/adblock.sh b/luci-app-adbyby-plus/root/usr/share/adbyby/adblock.sh
new file mode 100755
index 000000000..8224179dd
--- /dev/null
+++ b/luci-app-adbyby-plus/root/usr/share/adbyby/adblock.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+uclient-fetch --no-check-certificate -O - 'https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt' > /tmp/adnew.conf
+if [ -s "/tmp/adnew.conf" ];then
+ /usr/share/adbyby/ad-update
+fi
+
+rm -f /tmp/adbyby.updated
+sleep 10
+/etc/init.d/adbyby restart
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/adbybyfirst.sh b/luci-app-adbyby-plus/root/usr/share/adbyby/adbybyfirst.sh
new file mode 100755
index 000000000..532fe182d
--- /dev/null
+++ b/luci-app-adbyby-plus/root/usr/share/adbyby/adbybyfirst.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+PROG_PATH=$(pwd)
+$PROG_PATH/adbybyupdate.sh
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/adbybyupdate.sh b/luci-app-adbyby-plus/root/usr/share/adbyby/adbybyupdate.sh
new file mode 100755
index 000000000..5143cca3d
--- /dev/null
+++ b/luci-app-adbyby-plus/root/usr/share/adbyby/adbybyupdate.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+if [ ! -f "/tmp/adbyby.updated" ];then
+ wget_ok="0"
+ while [ "$wget_ok" = "0" ]
+ do
+ uclient-fetch --spider --quiet --timeout=3 http://www.baidu.com
+ if [ "$?" == "0" ]; then
+ wget_ok="1"
+
+ touch /tmp/md5.json && uclient-fetch --no-check-certificate -T 10 -O /tmp/md5.json https://adbyby.coding.net/p/xwhyc-rules/d/xwhyc-rules/git/raw/master/md5.json
+ adm5=$(md5sum /tmp/md5.json | awk -F' ' '{print $1}')
+ touch /tmp/adbyby/admd5.json && bmd5=$(md5sum /tmp/adbyby/admd5.json | awk -F' ' '{print $1}')
+ if [ "$adm5" == "$bmd5" ];then
+ echo "Rules MD5 are the same!"
+ echo $(date "+%Y-%m-%d %H:%M:%S") > /tmp/adbyby.updated
+ exit 0
+ elif [ -s /tmp/md5.json ];then
+
+ touch /tmp/lazy.txt && uclient-fetch --no-check-certificate -T 10 -O /tmp/lazy.txt https://adbyby.coding.net/p/xwhyc-rules/d/xwhyc-rules/git/raw/master/lazy.txt
+ touch /tmp/video.txt && uclient-fetch --no-check-certificate -T 10 -O /tmp/video.txt https://adbyby.coding.net/p/xwhyc-rules/d/xwhyc-rules/git/raw/master/video.txt
+
+ touch /tmp/local-md5.json && md5sum /tmp/lazy.txt /tmp/video.txt > /tmp/local-md5.json
+
+
+ lazy_local=$(grep 'lazy' /tmp/local-md5.json | awk -F' ' '{print $1}')
+ video_local=$(grep 'video' /tmp/local-md5.json | awk -F' ' '{print $1}')
+ lazy_online=$(sed 's/":"/\n/g' /tmp/md5.json | sed 's/","/\n/g' | sed -n '2p')
+ video_online=$(sed 's/":"/\n/g' /tmp/md5.json | sed 's/","/\n/g' | sed -n '4p')
+
+ if [ "$lazy_online"x == "$lazy_local"x -a "$video_online"x == "$video_local"x ]; then
+ echo "adbyby rules MD5 OK!"
+ mv /tmp/lazy.txt /tmp/adbyby/data/lazy.txt
+ mv /tmp/video.txt /tmp/adbyby/data/video.txt
+ mv /tmp/md5.json /tmp/adbyby/admd5.json
+ echo $(date "+%Y-%m-%d %H:%M:%S") > /tmp/adbyby.updated
+ fi
+ fi
+ else
+ sleep 10
+ fi
+ done
+
+ rm -f /tmp/adbyby/data/*.bak
+
+ kill -9 $(busybox ps -w | grep "/tmp/adbyby/adbyby" | grep -v grep | grep -v update| grep -v adblock | awk '{print $1}') >/dev/null 2>&1
+ /tmp/adbyby/adbyby >/dev/null 2>&1 &
+fi
+
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/adesc.conf b/luci-app-adbyby-plus/root/usr/share/adbyby/adesc.conf
new file mode 100644
index 000000000..c5898a128
--- /dev/null
+++ b/luci-app-adbyby-plus/root/usr/share/adbyby/adesc.conf
@@ -0,0 +1,3 @@
+weixin.qq.com
+qpic.cn
+imtt.qq.com
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/adhost.conf b/luci-app-adbyby-plus/root/usr/share/adbyby/adhost.conf
new file mode 100644
index 000000000..5f4f1a124
--- /dev/null
+++ b/luci-app-adbyby-plus/root/usr/share/adbyby/adhost.conf
@@ -0,0 +1,68 @@
+cbjs.baidu.com
+list.video.baidu.com
+nsclick.baidu.com
+play.baidu.com
+sclick.baidu.com
+tieba.baidu.com
+baidustatic.com
+bdimg.com
+bdstatic.com
+share.baidu.com
+hm.baidu.com
+v.baidu.com
+cpro.baidu.com
+1000fr.net
+atianqi.com
+56.com
+v-56.com
+acfun.com
+acfun.tv
+baofeng.com
+baofeng.net
+cntv.cn
+hoopchina.com.cn
+funshion.com
+fun.tv
+hitvs.cn
+hljtv.com
+iqiyi.com
+qiyi.com
+agn.aty.sohu.com
+itc.cn
+kankan.com
+ku6.com
+letv.com
+letvcloud.com
+letvimg.com
+pplive.cn
+pps.tv
+ppsimg.com
+pptv.com
+www.qq.com
+l.qq.com
+v.qq.com
+video.sina.com.cn
+tudou.com
+wasu.cn
+analytics-union.xunlei.com
+kankan.xunlei.com
+youku.com
+hunantv.com
+ifeng.com
+renren.com
+mediav.com
+cnbeta.com
+mydrivers.com
+168f.info
+doubleclick.net
+126.net
+sohu.com
+right.com.cn
+50bang.org
+you85.cn
+jiuzhilan.com
+googles.com
+cnbetacdn.com
+ptqy.gitv.tv
+admaster.com.cn
+serving-sys.com
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/admem.sh b/luci-app-adbyby-plus/root/usr/share/adbyby/admem.sh
new file mode 100755
index 000000000..36d6deb19
--- /dev/null
+++ b/luci-app-adbyby-plus/root/usr/share/adbyby/admem.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+if [ ! -f "/tmp/adbyby.updated" ];then
+ touch /tmp/adbyby.mem
+ wget_ok="0"
+ while [ "$wget_ok" = "0" ]
+ do
+ uclient-fetch --spider --quiet --tries=1 --timeout=3 www.baidu.com
+ if [ "$?" == "0" ]; then
+ wget_ok="1"
+
+ touch /tmp/md5.json && uclient-fetch --no-check-certificate -t 1 -T 10 -O /tmp/md5.json https://adbyby.coding.net/p/xwhyc-rules/d/xwhyc-rules/git/raw/master/md5.json
+ adm5=$(md5sum /tmp/md5.json | awk -F' ' '{print $1}')
+ touch /tmp/adbyby/admd5.json && bmd5=$(md5sum /tmp/adbyby/admd5.json | awk -F' ' '{print $1}')
+ if [ "$adm5" == "$bmd5" ];then
+ echo "Rules MD5 are the same!"
+ echo $(date "+%Y-%m-%d %H:%M:%S") > /tmp/adbyby.updated
+ exit 0
+ else
+
+ touch /tmp/lazy.txt && uclient-fetch --no-check-certificate -t 1 -T 10 -O /tmp/lazy.txt https://adbyby.coding.net/p/xwhyc-rules/d/xwhyc-rules/git/raw/master/lazy.txt
+ touch /tmp/video.txt && uclient-fetch --no-check-certificate -t 1 -T 10 -O /tmp/video.txt https://adbyby.coding.net/p/xwhyc-rules/d/xwhyc-rules/git/raw/master/video.txt
+
+ touch /tmp/local-md5.json && md5sum /tmp/lazy.txt /tmp/video.txt > /tmp/local-md5.json
+
+
+ lazy_local=$(grep 'lazy' /tmp/local-md5.json | awk -F' ' '{print $1}')
+ video_local=$(grep 'video' /tmp/local-md5.json | awk -F' ' '{print $1}')
+ lazy_online=$(sed 's/":"/\n/g' /tmp/md5.json | sed 's/","/\n/g' | sed -n '2p')
+ video_online=$(sed 's/":"/\n/g' /tmp/md5.json | sed 's/","/\n/g' | sed -n '4p')
+
+ if [ "$lazy_online"x == "$lazy_local"x -a "$video_online"x == "$video_local"x ]; then
+ echo "adbyby rules MD5 OK!"
+ mv /tmp/lazy.txt /tmp/adbyby/data/lazy.txt
+ mv /tmp/video.txt /tmp/adbyby/data/video.txt
+ mv /tmp/md5.json /tmp/adbyby/admd5.json
+ echo $(date "+%Y-%m-%d %H:%M:%S") > /tmp/adbyby.updated
+ fi
+ fi
+ else
+ sleep 10
+ fi
+ done
+
+ sleep 10 && /etc/init.d/adbyby restart
+fi
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/adupdate.sh b/luci-app-adbyby-plus/root/usr/share/adbyby/adupdate.sh
new file mode 100755
index 000000000..7ae9e6424
--- /dev/null
+++ b/luci-app-adbyby-plus/root/usr/share/adbyby/adupdate.sh
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+rm -f /usr/share/adbyby/data/*.bak
+
+touch /tmp/local-md5.json && md5sum /usr/share/adbyby/data/lazy.txt /usr/share/adbyby/data/video.txt > /tmp/local-md5.json
+touch /tmp/md5.json && uclient-fetch --no-check-certificate -T 10 -O /tmp/md5.json https://adbyby.coding.net/p/xwhyc-rules/d/xwhyc-rules/git/raw/master/md5.json
+
+lazy_local=$(grep 'lazy' /tmp/local-md5.json | awk -F' ' '{print $1}')
+video_local=$(grep 'video' /tmp/local-md5.json | awk -F' ' '{print $1}')
+lazy_online=$(sed 's/":"/\n/g' /tmp/md5.json | sed 's/","/\n/g' | sed -n '2p')
+video_online=$(sed 's/":"/\n/g' /tmp/md5.json | sed 's/","/\n/g' | sed -n '4p')
+
+if [ "$lazy_online"x != "$lazy_local"x -o "$video_online"x != "$video_local"x ]; then
+ echo "MD5 not match! Need update!"
+ touch /tmp/lazy.txt && uclient-fetch --no-check-certificate -T 10 -O /tmp/lazy.txt https://adbyby.coding.net/p/xwhyc-rules/d/xwhyc-rules/git/raw/master/lazy.txt
+ touch /tmp/video.txt && uclient-fetch --no-check-certificate -T 10 -O /tmp/video.txt https://adbyby.coding.net/p/xwhyc-rules/d/xwhyc-rules/git/raw/master/video.txt
+ touch /tmp/local-md5.json && md5sum /tmp/lazy.txt /tmp/video.txt > /tmp/local-md5.json
+ lazy_local=$(grep 'lazy' /tmp/local-md5.json | awk -F' ' '{print $1}')
+ video_local=$(grep 'video' /tmp/local-md5.json | awk -F' ' '{print $1}')
+ if [ "$lazy_online"x == "$lazy_local"x -a "$video_online"x == "$video_local"x ]; then
+ echo "New rules MD5 match!"
+ mv /tmp/lazy.txt /usr/share/adbyby/data/lazy.txt
+ mv /tmp/video.txt /usr/share/adbyby/data/video.txt
+ echo $(date +"%Y-%m-%d %H:%M:%S") > /tmp/adbyby.updated
+ fi
+else
+ echo "MD5 match! No need to update!"
+fi
+
+rm -f /tmp/lazy.txt /tmp/video.txt /tmp/local-md5.json /tmp/md5.json
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/blockip.conf b/luci-app-adbyby-plus/root/usr/share/adbyby/blockip.conf
new file mode 100644
index 000000000..55cb84b53
--- /dev/null
+++ b/luci-app-adbyby-plus/root/usr/share/adbyby/blockip.conf
@@ -0,0 +1 @@
+2.2.2.2
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.adblock b/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.adblock
new file mode 100644
index 000000000..e69de29bb
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.ads b/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.ads
new file mode 100644
index 000000000..ec1a22189
--- /dev/null
+++ b/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.ads
@@ -0,0 +1,4 @@
+address=/p.tanx.com/0.0.0.0
+address=/googlesyndication.com/0.0.0.0
+address=/linkvans.com/0.0.0.0
+server=/valf.atm.youku.com/114.114.114.114
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.esc b/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.esc
new file mode 100644
index 000000000..6cfd87056
--- /dev/null
+++ b/luci-app-adbyby-plus/root/usr/share/adbyby/dnsmasq.esc
@@ -0,0 +1,3 @@
+ipset=/weixin.qq.com/adbyby_wan
+ipset=/qpic.cn/adbyby_wan
+ipset=/imtt.qq.com/adbyby_wan
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/firewall.include b/luci-app-adbyby-plus/root/usr/share/adbyby/firewall.include
new file mode 100755
index 000000000..4dcec1e26
--- /dev/null
+++ b/luci-app-adbyby-plus/root/usr/share/adbyby/firewall.include
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+if [ -f /tmp/blockip.ipset ];then
+
+adbyby_enable=$(uci get adbyby.@adbyby[0].enable)
+
+if [ $adbyby_enable -eq 1 ]; then
+ if pidof adbyby>/dev/null; then
+ /etc/init.d/adbyby reload_rule
+ else
+ /etc/init.d/adbyby restart
+ fi
+fi
+
+fi
+
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/rule-count b/luci-app-adbyby-plus/root/usr/share/adbyby/rule-count
new file mode 100755
index 000000000..9f7388738
--- /dev/null
+++ b/luci-app-adbyby-plus/root/usr/share/adbyby/rule-count
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+find $1 -type f -exec cat {} \; | wc -l
\ No newline at end of file
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/rule-update b/luci-app-adbyby-plus/root/usr/share/adbyby/rule-update
new file mode 100755
index 000000000..95239bac8
--- /dev/null
+++ b/luci-app-adbyby-plus/root/usr/share/adbyby/rule-update
@@ -0,0 +1,36 @@
+#!/bin/sh -e
+
+url_md5() {
+ echo -n $1|md5sum|cut -d ' ' -f1
+}
+
+convert_rules() {
+mkdir -p /tmp/rules/data
+mkdir -p /tmp/rules/host
+
+uclient-fetch -q --no-check-certificate $1 -O /tmp/adnew.conf
+
+rulename=$(url_md5 $1)
+
+if [ -f /tmp/adnew.conf ]; then
+ if (grep -wq "address=" /tmp/adnew.conf) ; then
+ cp /tmp/adnew.conf /tmp/rules/data/$rulename.conf
+ elif (grep -wq -e"0.0.0.0" -e"127.0.0.1" /tmp/adnew.conf) ; then
+ cp /tmp/adnew.conf /tmp/rules/host/$rulename.txt
+ else
+ cat /tmp/adnew.conf | grep ^\|\|[^\*]*\^$ | sed -e 's:||:address\=\/:' -e 's:\^:/0\.0\.0\.0:' > /tmp/rules/data/$rulename.conf
+ fi
+fi
+rm -rf /tmp/adnew.conf
+}
+
+ARRAY=$(uci get adbyby.@adbyby[0].subscribe_url 2> /dev/null)
+
+rm -rf /tmp/rules
+
+i=1
+for j in $ARRAY
+do
+ convert_rules $j
+ i=`expr $i + 1`
+done
\ No newline at end of file
diff --git a/luci-app-adbyby-plus/root/usr/share/adbyby/rules.txt b/luci-app-adbyby-plus/root/usr/share/adbyby/rules.txt
new file mode 100644
index 000000000..5c44b0e8c
--- /dev/null
+++ b/luci-app-adbyby-plus/root/usr/share/adbyby/rules.txt
@@ -0,0 +1,15 @@
+! ------------------------------ ADByby 自定义过滤语法简表---------------------------------
+! -------------- 规则基于abp规则,并进行了字符替换部分的扩展-----------------------------
+! ABP规则请参考https://adblockplus.org/zh_CN/filters,下面为大致摘要
+! "!" 为行注释符,注释行以该符号起始作为一行注释语义,用于规则描述
+! "*" 为字符通配符,能够匹配0长度或任意长度的字符串,该通配符不能与正则语法混用。
+! "^" 为分隔符,可以是除了字母、数字或者 _ - . % 之外的任何字符。
+! "|" 为管线符号,来表示地址的最前端或最末端
+! "||" 为子域通配符,方便匹配主域名下的所有子域。
+! "~" 为排除标识符,通配符能过滤大多数广告,但同时存在误杀, 可以通过排除标识符修正误杀链接。
+! "##" 为元素选择器标识符,后面跟需要隐藏元素的CSS样式例如 #ad_id .ad_class
+!! 元素隐藏暂不支持全局规则和排除规则
+!! 字符替换扩展
+! 文本替换选择器标识符,后面跟需要替换的文本数据,格式:$s@模式字符串@替换后的文本@
+! 支持通配符*和?
+! -------------------------------------------------------------------------------------------
diff --git a/luci-app-zerotier/Makefile b/luci-app-zerotier/Makefile
new file mode 100644
index 000000000..80fa08c2a
--- /dev/null
+++ b/luci-app-zerotier/Makefile
@@ -0,0 +1,17 @@
+#
+# Copyright (C) 2008-2014 The LuCI Team
+#
+# This is free software, licensed under the Apache License, Version 2.0 .
+#
+
+include $(TOPDIR)/rules.mk
+
+LUCI_TITLE:=LuCI for Zerotier
+LUCI_DEPENDS:=+zerotier
+LUCI_PKGARCH:=all
+PKG_VERSION:=1.0
+PKG_RELEASE:=20
+
+include $(TOPDIR)/feeds/luci/luci.mk
+
+# call BuildPackage - OpenWrt buildroot signature
diff --git a/luci-app-zerotier/luasrc/controller/zerotier.lua b/luci-app-zerotier/luasrc/controller/zerotier.lua
new file mode 100644
index 000000000..9c69c063e
--- /dev/null
+++ b/luci-app-zerotier/luasrc/controller/zerotier.lua
@@ -0,0 +1,23 @@
+module("luci.controller.zerotier",package.seeall)
+
+function index()
+ if not nixio.fs.access("/etc/config/zerotier") then
+ return
+ end
+
+ entry({"admin","vpn"}, firstchild(), "VPN", 45).dependent = false
+
+ entry({"admin", "vpn", "zerotier"},firstchild(), _("ZeroTier")).dependent = false
+
+ entry({"admin", "vpn", "zerotier", "general"}, cbi("zerotier/settings"), _("Base Setting"), 1)
+ entry({"admin", "vpn", "zerotier", "log"}, form("zerotier/info"), _("Interface Info"), 2)
+
+ entry({"admin", "vpn", "zerotier", "status"}, call("act_status"))
+end
+
+function act_status()
+ local e = {}
+ e.running = luci.sys.call("pgrep /usr/bin/zerotier-one >/dev/null") == 0
+ luci.http.prepare_content("application/json")
+ luci.http.write_json(e)
+end
diff --git a/luci-app-zerotier/luasrc/model/cbi/zerotier/info.lua b/luci-app-zerotier/luasrc/model/cbi/zerotier/info.lua
new file mode 100644
index 000000000..199c468dd
--- /dev/null
+++ b/luci-app-zerotier/luasrc/model/cbi/zerotier/info.lua
@@ -0,0 +1,15 @@
+local fs = require "nixio.fs"
+local conffile = "/tmp/zero.info"
+
+f = SimpleForm("logview")
+
+t = f:field(TextValue, "conf")
+t.rmempty = true
+t.rows = 19
+function t.cfgvalue()
+ luci.sys.exec("for i in $(ifconfig | grep 'zt' | awk '{print $1}'); do ifconfig $i; done > /tmp/zero.info")
+ return fs.readfile(conffile) or ""
+end
+t.readonly="readonly"
+
+return f
diff --git a/luci-app-zerotier/luasrc/model/cbi/zerotier/settings.lua b/luci-app-zerotier/luasrc/model/cbi/zerotier/settings.lua
new file mode 100644
index 000000000..32ef1bbfc
--- /dev/null
+++ b/luci-app-zerotier/luasrc/model/cbi/zerotier/settings.lua
@@ -0,0 +1,27 @@
+a = Map("zerotier")
+a.title = translate("ZeroTier")
+a.description = translate("Zerotier is an open source, cross-platform and easy to use virtual LAN")
+
+a:section(SimpleSection).template = "zerotier/zerotier_status"
+
+t = a:section(NamedSection, "sample_config", "zerotier")
+t.anonymous = true
+t.addremove = false
+
+e = t:option(Flag, "enabled", translate("Enable"))
+e.default = 0
+e.rmempty=false
+
+e = t:option(DynamicList, "join", translate('ZeroTier Network ID'))
+e.password = true
+e.rmempty = false
+
+e = t:option(Flag, "nat", translate("Auto NAT Clients"))
+e.description = translate("Allow zerotier clients access your LAN network")
+e.default = 0
+e.rmempty = false
+
+e = t:option(DummyValue, "opennewwindow", translate(""))
+e.description = translate("Create or manage your zerotier network, and auth clients who could access")
+
+return a
diff --git a/luci-app-zerotier/luasrc/view/zerotier/zerotier_status.htm b/luci-app-zerotier/luasrc/view/zerotier/zerotier_status.htm
new file mode 100644
index 000000000..9d216c5d9
--- /dev/null
+++ b/luci-app-zerotier/luasrc/view/zerotier/zerotier_status.htm
@@ -0,0 +1,22 @@
+
+
+
diff --git a/luci-app-zerotier/po/zh-cn/zerotier.po b/luci-app-zerotier/po/zh-cn/zerotier.po
new file mode 100644
index 000000000..9ed1270b3
--- /dev/null
+++ b/luci-app-zerotier/po/zh-cn/zerotier.po
@@ -0,0 +1,25 @@
+msgid ""
+msgstr ""
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Gtranslator 2.91.7\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgid "Zerotier is an open source, cross-platform and easy to use virtual LAN"
+msgstr "Zerotier 是一个开源,跨平台,而且适合内网穿透互联的傻瓜配置虚拟 VPN LAN"
+
+msgid "Auto NAT Clients"
+msgstr "自动允许客户端 NAT"
+
+msgid "Allow zerotier clients access your LAN network"
+msgstr "允许 Zerotier 的拨入客户端访问路由器 LAN 资源(需要在 Zerotier 管理页面设定到 LAN 网段的路由表)"
+
+msgid "Create or manage your zerotier network, and auth clients who could access"
+msgstr "点击跳转到 Zerotier 官网管理平台,新建或者管理网络,并允许客户端接入访问你私人网路(新接入的节点默认不允许访问)"
+
+msgid "Base Setting"
+msgstr "基本设置"
+
+msgid "Interface Info"
+msgstr "接口信息"
diff --git a/luci-app-zerotier/root/etc/init.d/zerotier b/luci-app-zerotier/root/etc/init.d/zerotier
new file mode 100755
index 000000000..0403e5d17
--- /dev/null
+++ b/luci-app-zerotier/root/etc/init.d/zerotier
@@ -0,0 +1,113 @@
+#!/bin/sh /etc/rc.common
+
+START=99
+
+USE_PROCD=1
+
+PROG=/usr/bin/zerotier-one
+CONFIG_PATH=/var/lib/zerotier-one
+
+service_triggers() {
+ procd_add_reload_trigger "zerotier"
+ procd_add_interface_trigger "interface.*.up" wan /etc/init.d/zerotier restart
+}
+
+section_enabled() {
+ config_get_bool enabled "$1" 'enabled' 0
+ [ $enabled -gt 0 ]
+}
+
+start_instance() {
+ local cfg="$1"
+ local port secret config_path
+ local ARGS=""
+
+ if ! section_enabled "$cfg"; then
+ echo "disabled in config"
+ return 1
+ fi
+
+ [ -d /etc/config/zero ] || mkdir -p /etc/config/zero
+ config_path=/etc/config/zero
+
+ config_get_bool port $cfg 'port'
+ config_get secret $cfg 'secret'
+
+ # Remove existing link or folder
+ rm -rf $CONFIG_PATH
+
+ # Create link from CONFIG_PATH to config_path
+ if [ -n "$config_path" -a "$config_path" != $CONFIG_PATH ]; then
+ if [ ! -d "$config_path" ]; then
+ echo "ZeroTier config_path does not exist: $config_path"
+ return
+ fi
+
+ ln -s $config_path $CONFIG_PATH
+ fi
+
+ mkdir -p $CONFIG_PATH/networks.d
+
+ if [ -n "$port" ]; then
+ ARGS="$ARGS -p$port"
+ fi
+
+ if [ "$secret" = "generate" ]; then
+ echo "Generate secret - please wait..."
+ local sf="/tmp/zt.$cfg.secret"
+
+ zerotier-idtool generate "$sf" > /dev/null
+ [ $? -ne 0 ] && return 1
+
+ secret="$(cat $sf)"
+ rm "$sf"
+
+ uci set zerotier.$cfg.secret="$secret"
+ uci commit zerotier
+ fi
+
+ if [ -n "$secret" ]; then
+ echo "$secret" > $CONFIG_PATH/identity.secret
+ # make sure there is not previous identity.public
+ rm -f $CONFIG_PATH/identity.public
+ fi
+
+ add_join() {
+ # an (empty) config file will cause ZT to join a network
+ touch $CONFIG_PATH/networks.d/$1.conf
+ }
+
+ config_list_foreach $cfg 'join' add_join
+
+ procd_open_instance
+ procd_set_param command $PROG $ARGS $CONFIG_PATH
+ procd_set_param stderr 1
+ procd_close_instance
+}
+
+start_service() {
+ config_load 'zerotier'
+ config_foreach start_instance 'zerotier'
+ touch /tmp/zero.log && /etc/zerotier.start > /tmp/zero.log 2>&1 &
+}
+
+stop_instance() {
+ rm -f /tmp/zero.log
+ local cfg="$1"
+
+ /etc/zerotier.stop > /tmp/zero.log 2>&1 &
+
+ # Remove existing link or folder
+ rm -f $CONFIG_PATH/networks.d/*.conf
+ rm -rf $CONFIG_PATH
+}
+
+stop_service() {
+ config_load 'zerotier'
+ config_foreach stop_instance 'zerotier'
+}
+
+reload_service() {
+ stop
+ start
+}
\ No newline at end of file
diff --git a/luci-app-zerotier/root/etc/uci-defaults/40_luci-zerotier b/luci-app-zerotier/root/etc/uci-defaults/40_luci-zerotier
new file mode 100755
index 000000000..95f0ccfc9
--- /dev/null
+++ b/luci-app-zerotier/root/etc/uci-defaults/40_luci-zerotier
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+uci -q batch <<-EOF >/dev/null
+ delete ucitrack.@zerotier[-1]
+ add ucitrack zerotier
+ set ucitrack.@zerotier[-1].init=zerotier
+ commit ucitrack
+ delete firewall.zerotier
+ set firewall.zerotier=include
+ set firewall.zerotier.type=script
+ set firewall.zerotier.path=/etc/zerotier.start
+ set firewall.zerotier.reload=1
+ commit firewall
+EOF
+
+rm -f /tmp/luci-indexcache
+exit 0
diff --git a/luci-app-zerotier/root/etc/zerotier.start b/luci-app-zerotier/root/etc/zerotier.start
new file mode 100755
index 000000000..b43e5f974
--- /dev/null
+++ b/luci-app-zerotier/root/etc/zerotier.start
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+zero_enable="$(uci get zerotier.sample_config.enabled)"
+
+[ "${zero_enable}" -ne "1" ] && exit 0
+
+[ -f "/tmp/zero.log" ] && {
+ while [ "$(ifconfig | grep 'zt' | awk '{print $1}')" = "" ]
+ do
+ sleep 1
+ done
+}
+
+nat_enable="$(uci get zerotier.sample_config.nat)"
+zt0="$(ifconfig | grep 'zt' | awk '{print $1}')"
+echo "${zt0}" > "/tmp/zt.nif"
+
+[ "${nat_enable}" -eq "1" ] && {
+ for i in ${zt0}
+ do
+ ip_segment=""
+ iptables -I FORWARD -i "$i" -j ACCEPT
+ iptables -I FORWARD -o "$i" -j ACCEPT
+ iptables -t nat -I POSTROUTING -o "$i" -j MASQUERADE
+ ip_segment="$(ip route | grep "dev $i proto kernel" | awk '{print $1}')"
+ iptables -t nat -I POSTROUTING -s "${ip_segment}" -j MASQUERADE
+ done
+}
diff --git a/luci-app-zerotier/root/etc/zerotier.stop b/luci-app-zerotier/root/etc/zerotier.stop
new file mode 100755
index 000000000..07450183e
--- /dev/null
+++ b/luci-app-zerotier/root/etc/zerotier.stop
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+zt0="$(ifconfig | grep 'zt' | awk '{print $1}')"
+[ -z "${zt0}" ] && zt0="$(cat "/tmp/zt.nif")"
+
+for i in ${zt0}
+do
+ ip_segment=""
+ iptables -D FORWARD -i "$i" -j ACCEPT 2>/dev/null
+ iptables -D FORWARD -o "$i" -j ACCEPT 2>/dev/null
+ iptables -t nat -D POSTROUTING -o "$i" -j MASQUERADE 2>/dev/null
+ ip_segment="$(ip route | grep "dev $i proto" | awk '{print $1}')"
+ iptables -t nat -D POSTROUTING -s "${ip_segment}" -j MASQUERADE 2>/dev/null
+ echo "zt interface $i is stopped!"
+done
\ No newline at end of file
diff --git a/luci-app-zerotier/root/etc/zerotier/zerotier.log b/luci-app-zerotier/root/etc/zerotier/zerotier.log
new file mode 100644
index 000000000..e69de29bb
diff --git a/luci-app-zerotier/root/usr/share/rpcd/acl.d/luci-app-zerotier.json b/luci-app-zerotier/root/usr/share/rpcd/acl.d/luci-app-zerotier.json
new file mode 100644
index 000000000..2724e99bf
--- /dev/null
+++ b/luci-app-zerotier/root/usr/share/rpcd/acl.d/luci-app-zerotier.json
@@ -0,0 +1,11 @@
+{
+ "luci-app-zerotier": {
+ "description": "Grant UCI access for luci-app-zerotier",
+ "read": {
+ "uci": [ "zerotier" ]
+ },
+ "write": {
+ "uci": [ "zerotier" ]
+ }
+ }
+}