diff --git a/mobile/src/main/scala/com/github/shadowsocks/acl/Acl.scala b/mobile/src/main/scala/com/github/shadowsocks/acl/Acl.scala index 1e059129..4974024e 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/acl/Acl.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/acl/Acl.scala @@ -19,20 +19,19 @@ import scala.io.Source class Acl { @DatabaseField(generatedId = true) var id: Int = _ - val bypassHostnames = new mutable.SortedList[String]() - val proxyHostnames = new mutable.SortedList[String]() + + val hostnames = new mutable.SortedList[String]() val subnets = new mutable.SortedList[Subnet]() val urls = new mutable.SortedList[String]() + @DatabaseField var bypass: Boolean = _ def isUrl(url: String): Boolean = url.startsWith("http://") || url.startsWith("https://") def fromAcl(other: Acl): Acl = { - bypassHostnames.clear() - bypassHostnames ++= other.bypassHostnames - proxyHostnames.clear() - proxyHostnames ++= other.proxyHostnames + hostnames.clear() + hostnames ++= other.hostnames subnets.clear() subnets ++= other.subnets urls.clear() @@ -40,16 +39,11 @@ class Acl { bypass = other.bypass this } + def fromSource(value: Source, defaultBypass: Boolean = true): Acl = { - bypassHostnames.clear() - proxyHostnames.clear() - this.subnets.clear() - this.urls.clear() + subnets.clear() + urls.clear() bypass = defaultBypass - lazy val bypassSubnets = new mutable.SortedList[Subnet]() - lazy val proxySubnets = new mutable.SortedList[Subnet]() - var hostnames: mutable.SortedList[String] = if (defaultBypass) proxyHostnames else bypassHostnames - var subnets: mutable.SortedList[Subnet] = if (defaultBypass) proxySubnets else bypassSubnets var in_urls = false for (line <- value.getLines()) (line.trim.indexOf('#') match { case 0 => { @@ -65,17 +59,12 @@ class Acl { } case index => if (!in_urls) line else "" }).trim match { + // Ignore all section controls case "[outbound_block_list]" => - hostnames = null - subnets = null case "[black_list]" | "[bypass_list]" => - hostnames = bypassHostnames - subnets = bypassSubnets case "[white_list]" | "[proxy_list]" => - hostnames = proxyHostnames - subnets = proxySubnets - case "[reject_all]" | "[bypass_all]" => bypass = true - case "[accept_all]" | "[proxy_all]" => bypass = false + case "[reject_all]" | "[bypass_all]" => + case "[accept_all]" | "[proxy_all]" => case input if subnets != null && input.nonEmpty => try subnets += Subnet.fromString(input) catch { case _: IllegalArgumentException => if (isUrl(input)) { urls += input @@ -85,7 +74,6 @@ class Acl { } case _ => } - this.subnets ++= (if (bypass) proxySubnets else bypassSubnets) this } final def fromId(id: String): Acl = fromSource(Source.fromFile(Acl.getFile(id))) @@ -103,21 +91,15 @@ class Acl { } result.append("\n#NETWORK_ACL_END\n") } + result.append("\n") } if (result.isEmpty) { - result.append(if (bypass) "[bypass_all]\n" else "[proxy_all]\n") + result.append("[bypass_all]\n") } - val (bypassList, proxyList) = - if (bypass) (bypassHostnames.toStream, subnets.toStream.map(_.toString) #::: proxyHostnames.toStream) - else (subnets.toStream.map(_.toString) #::: bypassHostnames.toStream, proxyHostnames.toStream) - if (bypassList.nonEmpty) { - result.append("[bypass_list]\n") - result.append(bypassList.mkString("\n")) - result.append('\n') - } - if (proxyList.nonEmpty) { + val list = subnets.toStream.map(_.toString) #::: hostnames.toStream + if (list.nonEmpty) { result.append("[proxy_list]\n") - result.append(proxyList.mkString("\n")) + result.append(list.mkString("\n")) result.append('\n') } result.toString @@ -127,7 +109,7 @@ class Acl { getAclString(false) } - def isValidCustomRules: Boolean = bypass && bypassHostnames.isEmpty + def isValidCustomRules: Boolean = !hostnames.isEmpty // Don't change: dummy fields for OrmLite interaction diff --git a/mobile/src/main/scala/com/github/shadowsocks/acl/CustomRulesFragment.scala b/mobile/src/main/scala/com/github/shadowsocks/acl/CustomRulesFragment.scala index 9900c2b2..6df3a281 100644 --- a/mobile/src/main/scala/com/github/shadowsocks/acl/CustomRulesFragment.scala +++ b/mobile/src/main/scala/com/github/shadowsocks/acl/CustomRulesFragment.scala @@ -125,7 +125,7 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi }) } - def getItemCount: Int = acl.subnets.size + acl.proxyHostnames.size + acl.urls.size + def getItemCount: Int = acl.subnets.size + acl.hostnames.size + acl.urls.size def onBindViewHolder(vh: AclRuleViewHolder, i: Int): Unit = { val j = i - acl.urls.size val k = i - acl.subnets.size - acl.urls.size @@ -134,7 +134,7 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi else if (k < 0) vh.bind(acl.subnets(j)) else - vh.bind(acl.proxyHostnames(k)) + vh.bind(acl.hostnames(k)) } def onCreateViewHolder(vg: ViewGroup, i: Int) = new AclRuleViewHolder(LayoutInflater.from(vg.getContext) .inflate(android.R.layout.simple_list_item_1, vg, false)) @@ -151,18 +151,18 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi apply() index } else -1 - def addHostname(hostname: String): Int = if (acl.proxyHostnames.add(hostname)) { - val index = acl.proxyHostnames.indexOf(hostname) + acl.urls.size + acl.subnets.size + def addHostname(hostname: String): Int = if (acl.hostnames.add(hostname)) { + val index = acl.hostnames.indexOf(hostname) + acl.urls.size + acl.subnets.size notifyItemInserted(index) apply() index } else -1 def addToProxy(input: String): Int = { - val acl = new Acl().fromSource(Source.fromString(input), defaultBypass = true) + val acl = new Acl().fromSource(Source.fromString(input)) var result = -1 for (url <- acl.urls) result = addUrl(url) - for (hostname <- acl.proxyHostnames) result = addHostname(hostname) - if (acl.bypass) for (subnet <- acl.subnets) result = addSubnet(subnet) + for (hostname <- acl.hostnames) result = addHostname(hostname) + for (subnet <- acl.subnets) result = addSubnet(subnet) result } def addFromTemplate(template: Int, text: CharSequence): Int = template match { @@ -186,8 +186,8 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi undoManager.remove((i, acl.subnets(j))) acl.subnets.remove(j) } else { - undoManager.remove((i, acl.proxyHostnames(k))) - acl.proxyHostnames.remove(k) + undoManager.remove((i, acl.hostnames(k))) + acl.hostnames.remove(k) } notifyItemRemoved(i) apply() @@ -202,9 +202,9 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi acl.urls.remove(hostname) apply() } else { - notifyItemRemoved(acl.proxyHostnames.indexOf(hostname) + notifyItemRemoved(acl.hostnames.indexOf(hostname) + acl.urls.size + acl.subnets.size) - acl.proxyHostnames.remove(hostname) + acl.hostnames.remove(hostname) apply() } } @@ -221,8 +221,8 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi apply() } } else { - if (acl.proxyHostnames.insert(hostname)) { - notifyItemInserted(acl.proxyHostnames.indexOf(hostname) + acl.urls.size + acl.subnets.size) + if (acl.hostnames.insert(hostname)) { + notifyItemInserted(acl.hostnames.indexOf(hostname) + acl.urls.size + acl.subnets.size) apply() } } @@ -236,7 +236,7 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi selectedItems.clear() selectedItems ++= acl.urls selectedItems ++= acl.subnets - selectedItems ++= acl.proxyHostnames + selectedItems ++= acl.hostnames onSelectedItemsUpdated() notifyDataSetChanged() } @@ -245,7 +245,7 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi val j = i - acl.subnets.size try { (if (j < 0) acl.subnets(i).address.getHostAddress.substring(0, 1) else { - val hostname = acl.proxyHostnames(i) + val hostname = acl.hostnames(i) PATTERN_DOMAIN.findFirstMatchIn(hostname) match { case Some(m) => m.matched.replaceAll("\\\\.", ".") // don't convert IDN yet case None => hostname @@ -341,7 +341,7 @@ class CustomRulesFragment extends ToolbarFragment with Toolbar.OnMenuItemClickLi case R.id.action_import_gfwlist => val acl = new Acl().fromId(Acl.GFWLIST) acl.subnets.foreach(adapter.addSubnet) - acl.proxyHostnames.foreach(adapter.addHostname) + acl.hostnames.foreach(adapter.addHostname) true case _ => false } diff --git a/project/build.properties b/project/build.properties new file mode 100644 index 00000000..c091b86c --- /dev/null +++ b/project/build.properties @@ -0,0 +1 @@ +sbt.version=0.13.16