Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
59f02cfa53 | ||
|
|
bd782dae98 | ||
|
|
ea738d17d7 | ||
|
|
915b1a74b1 | ||
|
|
9898ab88e0 | ||
|
|
c082a23c37 | ||
|
|
6636cf815d | ||
|
|
6df8f14fb2 | ||
|
|
0b88881fa4 | ||
|
|
85532a6b48 | ||
|
|
93274ffb04 |
@@ -20,7 +20,7 @@ lazy val commonSettings = Seq(
|
||||
resConfigs := Seq("ja", "ko", "ru", "zh-rCN", "zh-rTW")
|
||||
)
|
||||
|
||||
val supportLibsVersion = "25.2.0"
|
||||
val supportLibsVersion = "25.3.1"
|
||||
lazy val root = Project(id = "shadowsocks-android", base = file("."))
|
||||
.settings(commonSettings)
|
||||
.aggregate(plugin, mobile)
|
||||
|
||||
+17
-7
@@ -1,34 +1,44 @@
|
||||
enablePlugins(AndroidApp)
|
||||
enablePlugins(AndroidGms)
|
||||
|
||||
android.useSupportVectors
|
||||
|
||||
name := "shadowsocks"
|
||||
version := "4.1.4"
|
||||
versionCode := Some(184)
|
||||
version := "4.1.6"
|
||||
versionCode := Some(186)
|
||||
|
||||
proguardOptions ++=
|
||||
"-keep class com.github.shadowsocks.JniHelper { *; }" ::
|
||||
"-dontwarn com.evernote.android.job.gcm.**" ::
|
||||
"-dontwarn com.evernote.android.job.util.GcmAvailableHelper" ::
|
||||
"-dontwarn com.google.android.gms.internal.**" ::
|
||||
"-dontwarn com.j256.ormlite.**" ::
|
||||
"-dontwarn okio.**" ::
|
||||
"-dontwarn org.xbill.**" ::
|
||||
"-keep public class com.evernote.android.job.v21.PlatformJobService" ::
|
||||
"-keep public class com.evernote.android.job.v14.PlatformAlarmService" ::
|
||||
"-keep public class com.evernote.android.job.v14.PlatformAlarmReceiver" ::
|
||||
"-keep public class com.evernote.android.job.JobBootReceiver" ::
|
||||
"-keep public class com.evernote.android.job.JobRescheduleService" ::
|
||||
"-keep class com.github.shadowsocks.JniHelper { *; }" ::
|
||||
Nil
|
||||
|
||||
val playServicesVersion = "10.2.1"
|
||||
resolvers += Resolver.jcenterRepo
|
||||
libraryDependencies ++=
|
||||
"com.futuremind.recyclerfastscroll" % "fastscroll" % "0.2.5" ::
|
||||
"com.evernote" % "android-job" % "1.1.8" ::
|
||||
"com.evernote" % "android-job" % "1.1.9" ::
|
||||
"com.github.jorgecastilloprz" % "fabprogresscircle" % "1.01" ::
|
||||
"com.google.android.gms" % "play-services-ads" % playServicesVersion ::
|
||||
"com.google.android.gms" % "play-services-analytics" % playServicesVersion ::
|
||||
"com.google.android.gms" % "play-services-gcm" % playServicesVersion ::
|
||||
"com.google.firebase" % "firebase-config" % playServicesVersion ::
|
||||
"com.j256.ormlite" % "ormlite-android" % "5.0" ::
|
||||
"com.mikepenz" % "crossfader" % "1.5.0" ::
|
||||
"com.mikepenz" % "fastadapter" % "2.5.0" ::
|
||||
"com.mikepenz" % "iconics-core" % "2.8.2" ::
|
||||
"com.mikepenz" % "fastadapter" % "2.5.2" ::
|
||||
"com.mikepenz" % "iconics-core" % "2.8.3" ::
|
||||
"com.mikepenz" % "materialdrawer" % "5.9.0" ::
|
||||
"com.mikepenz" % "materialize" % "1.0.1" ::
|
||||
"com.squareup.okhttp3" % "okhttp" % "3.6.0" ::
|
||||
"com.squareup.okhttp3" % "okhttp" % "3.7.0" ::
|
||||
"com.twofortyfouram" % "android-plugin-api-for-locale" % "1.0.2" ::
|
||||
"dnsjava" % "dnsjava" % "2.1.8" ::
|
||||
"eu.chainfire" % "libsuperuser" % "1.0.0.201704021214" ::
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "261400168171",
|
||||
"firebase_url": "https://admob-app-id-3330146721.firebaseio.com",
|
||||
"project_id": "admob-app-id-3330146721",
|
||||
"storage_bucket": "admob-app-id-3330146721.appspot.com"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:261400168171:android:dbdd6331c434162f",
|
||||
"android_client_info": {
|
||||
"package_name": "com.github.shadowsocks"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "261400168171-sfik8o3pj7e243583olorh7s5974vab1.apps.googleusercontent.com",
|
||||
"client_type": 1,
|
||||
"android_info": {
|
||||
"package_name": "com.github.shadowsocks",
|
||||
"certificate_hash": "58a90f84cfe99d4280aec677c9a1292fae131677"
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_id": "261400168171-g7aelv5bu012ojr7dod7lq09c9anjimh.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyCee3fAad7nb3YsxeUO9mqqHFfAvsSCbVs"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"analytics_service": {
|
||||
"status": 1
|
||||
},
|
||||
"appinvite_service": {
|
||||
"status": 1,
|
||||
"other_platform_oauth_client": []
|
||||
},
|
||||
"ads_service": {
|
||||
"status": 2
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
Submodule mobile/src/main/jni/shadowsocks-libev updated: de0cebb62e...aaff27ed4d
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<defaultsMap>
|
||||
<entry>
|
||||
<key>proxy_url</key>
|
||||
<value>https://www.socks123.pw/get.php</value>
|
||||
</entry>
|
||||
</defaultsMap>
|
||||
@@ -21,7 +21,6 @@
|
||||
package com.github.shadowsocks
|
||||
|
||||
import java.io.{File, IOException}
|
||||
import java.net.InetAddress
|
||||
import java.util
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.{Timer, TimerTask}
|
||||
@@ -127,12 +126,8 @@ trait BaseService extends Service {
|
||||
|
||||
def connect() {
|
||||
profile.name = profile.getName // save original name before it's (possibly) overwritten by IP addresses
|
||||
if (profile.host == "198.199.101.152") {
|
||||
val holder = app.containerHolder
|
||||
val container = holder.getContainer
|
||||
val url = container.getString("proxy_url")
|
||||
val sig = Utils.getSignature(this)
|
||||
|
||||
if (profile.host == "198.199.101.152") {
|
||||
val client = new OkHttpClient.Builder()
|
||||
.dns(hostname => Utils.resolve(hostname, enableIPv6 = false) match {
|
||||
case Some(ip) => util.Arrays.asList(InetAddress.getByName(ip))
|
||||
@@ -143,10 +138,10 @@ trait BaseService extends Service {
|
||||
.readTimeout(30, TimeUnit.SECONDS)
|
||||
.build()
|
||||
val requestBody = new FormBody.Builder()
|
||||
.add("sig", sig)
|
||||
.add("sig", Utils.getSignature(this))
|
||||
.build()
|
||||
val request = new Request.Builder()
|
||||
.url(url)
|
||||
.url(app.remoteConfig.getString("proxy_url"))
|
||||
.post(requestBody)
|
||||
.build()
|
||||
|
||||
@@ -277,7 +272,6 @@ trait BaseService extends Service {
|
||||
|
||||
override def onCreate() {
|
||||
super.onCreate()
|
||||
app.refreshContainerHolder()
|
||||
app.updateAssets()
|
||||
}
|
||||
|
||||
@@ -302,23 +296,12 @@ trait BaseService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
def getBlackList: String = {
|
||||
val default = getString(R.string.black_list)
|
||||
try {
|
||||
val container = app.containerHolder.getContainer
|
||||
val update = container.getString("black_list_lite")
|
||||
val list = if (update == null || update.isEmpty) default else update
|
||||
"exclude = " + list + ";"
|
||||
} catch {
|
||||
case _: Exception => "exclude = " + default + ";"
|
||||
}
|
||||
}
|
||||
|
||||
protected def buildPluginCommandLine(): ArrayBuffer[String] = {
|
||||
val result = ArrayBuffer(pluginPath)
|
||||
if (TcpFastOpen.sendEnabled) result += "--fast-open"
|
||||
result
|
||||
}
|
||||
|
||||
protected final def buildShadowsocksConfig(file: String): String = {
|
||||
val config = new JSONObject()
|
||||
.put("server", profile.host)
|
||||
@@ -332,13 +315,6 @@ trait BaseService extends Service {
|
||||
file
|
||||
}
|
||||
|
||||
private final def buildRemoteDns(remoteDns: String): String = {
|
||||
val addr = InetAddress.getByName(remoteDns)
|
||||
if (addr.isInstanceOf[Inet6Address])
|
||||
return "[" + remoteDns + "]"
|
||||
remoteDns
|
||||
}
|
||||
|
||||
protected final def buildOvertureConfig(file: String): String = {
|
||||
val config = new JSONObject()
|
||||
.put("BindAddress", ":" + (profile.localPort + 53))
|
||||
@@ -350,7 +326,10 @@ trait BaseService extends Service {
|
||||
def makeDns(name: String, address: String, edns: Boolean = true) = {
|
||||
val dns = new JSONObject()
|
||||
.put("Name", name)
|
||||
.put("Address", address + ":53")
|
||||
.put("Address", (Utils.parseNumericAddress(address) match {
|
||||
case _: Inet6Address => '[' + address + ']'
|
||||
case _ => address
|
||||
}) + ":53")
|
||||
.put("Timeout", 6)
|
||||
.put("EDNSClientSubnet", new JSONObject().put("Policy", "disable"))
|
||||
if (edns) dns
|
||||
@@ -359,24 +338,25 @@ trait BaseService extends Service {
|
||||
else dns.put("Protocol", "udp")
|
||||
dns
|
||||
}
|
||||
val remoteDns = new JSONArray(profile.remoteDns.split(",").zipWithIndex.map {
|
||||
case (dns, i) => makeDns("UserDef-" + i, dns.trim)
|
||||
})
|
||||
profile.route match {
|
||||
case Acl.BYPASS_CHN | Acl.BYPASS_LAN_CHN | Acl.GFWLIST | Acl.CUSTOM_RULES => config
|
||||
.put("PrimaryDNS", new JSONArray(Array(
|
||||
makeDns("Primary-1", "119.29.29.29", edns = false),
|
||||
makeDns("Primary-2", "114.114.114.114", edns = false)
|
||||
)))
|
||||
.put("AlternativeDNS", new JSONArray().put(makeDns("Alternative",
|
||||
buildRemoteDns(profile.remoteDns.trim))))
|
||||
.put("AlternativeDNS", remoteDns)
|
||||
.put("IPNetworkFile", "china_ip_list.txt")
|
||||
.put("DomainFile", "gfwlist.txt")
|
||||
case Acl.CHINALIST => config
|
||||
.put("PrimaryDNS", new JSONArray().put(makeDns("Primary", "119.29.29.29")))
|
||||
.put("AlternativeDNS", new JSONArray().put(makeDns("Alternative",
|
||||
buildRemoteDns(profile.remoteDns.trim))))
|
||||
.put("AlternativeDNS", remoteDns)
|
||||
case _ => config
|
||||
.put("PrimaryDNS", new JSONArray().put(makeDns("Primary",
|
||||
buildRemoteDns(profile.remoteDns.trim))))
|
||||
.put("AlternativeDNS", new JSONArray().put(makeDns("Alternative", "208.67.222.222")))
|
||||
.put("PrimaryDNS", remoteDns)
|
||||
// no need to setup AlternativeDNS in Acl.ALL/BYPASS_LAN mode
|
||||
.put("OnlyPrimaryDNS", true)
|
||||
}
|
||||
IOUtils.writeString(new File(getFilesDir, file), config.toString)
|
||||
file
|
||||
|
||||
@@ -384,13 +384,14 @@ class MainActivity extends Activity with ServiceBoundContext with Drawer.OnDrawe
|
||||
displayFragment(new AboutFragment)
|
||||
case DRAWER_FAQ => launchUrl(getString(R.string.faq_url))
|
||||
case DRAWER_CUSTOM_RULES => displayFragment(new CustomRulesFragment)
|
||||
case _ => // ignore
|
||||
}
|
||||
true // unexpected cases will throw exception
|
||||
}
|
||||
|
||||
protected override def onResume() {
|
||||
super.onResume()
|
||||
app.refreshContainerHolder()
|
||||
app.remoteConfig.fetch()
|
||||
state match {
|
||||
case State.STOPPING | State.CONNECTING =>
|
||||
case _ => hideCircle()
|
||||
|
||||
@@ -21,9 +21,7 @@
|
||||
package com.github.shadowsocks
|
||||
|
||||
import java.io.{File, FileOutputStream, IOException}
|
||||
import java.util
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
@@ -39,8 +37,8 @@ import com.github.shadowsocks.database.{DBHelper, Profile, ProfileManager}
|
||||
import com.github.shadowsocks.utils.CloseUtils._
|
||||
import com.github.shadowsocks.utils._
|
||||
import com.google.android.gms.analytics.{GoogleAnalytics, HitBuilders, StandardExceptionParser, Tracker}
|
||||
import com.google.android.gms.common.api.ResultCallback
|
||||
import com.google.android.gms.tagmanager.{ContainerHolder, TagManager}
|
||||
import com.google.firebase.FirebaseApp
|
||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
|
||||
import com.j256.ormlite.logger.LocalLog
|
||||
import eu.chainfire.libsuperuser.Shell
|
||||
|
||||
@@ -61,8 +59,7 @@ object ShadowsocksApplication {
|
||||
class ShadowsocksApplication extends Application {
|
||||
import ShadowsocksApplication._
|
||||
|
||||
final val SIG_FUNC = "getSignature"
|
||||
var containerHolder: ContainerHolder = _
|
||||
lazy val remoteConfig = FirebaseRemoteConfig.getInstance()
|
||||
lazy val tracker: Tracker = GoogleAnalytics.getInstance(this).newTracker(R.xml.tracker)
|
||||
lazy val settings: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
lazy val editor: SharedPreferences.Editor = settings.edit
|
||||
@@ -149,35 +146,16 @@ class ShadowsocksApplication extends Application {
|
||||
if (!BuildConfig.DEBUG) java.lang.System.setProperty(LocalLog.LOCAL_LOG_LEVEL_PROPERTY, "ERROR")
|
||||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
|
||||
checkChineseLocale(getResources.getConfiguration)
|
||||
val tm = TagManager.getInstance(this)
|
||||
val pending = tm.loadContainerPreferNonDefault("GTM-NT8WS8", R.raw.gtm_default_container)
|
||||
val callback = new ResultCallback[ContainerHolder] {
|
||||
override def onResult(holder: ContainerHolder) {
|
||||
if (!holder.getStatus.isSuccess) {
|
||||
return
|
||||
}
|
||||
containerHolder = holder
|
||||
val container = holder.getContainer
|
||||
container.registerFunctionCallMacroCallback(SIG_FUNC,
|
||||
(functionName: String, parameters: util.Map[String, AnyRef]) => {
|
||||
if (functionName == SIG_FUNC) {
|
||||
Utils.getSignature(getApplicationContext)
|
||||
}
|
||||
null
|
||||
})
|
||||
}
|
||||
}
|
||||
pending.setResultCallback(callback, 2, TimeUnit.SECONDS)
|
||||
|
||||
FirebaseApp.initializeApp(this)
|
||||
remoteConfig.setDefaults(R.xml.default_configs);
|
||||
remoteConfig.fetch().addOnCompleteListener(task => if (task.isSuccessful) remoteConfig.activateFetched())
|
||||
|
||||
JobManager.create(this).addJobCreator(DonaldTrump)
|
||||
|
||||
TcpFastOpen.enabled(settings.getBoolean(Key.tfo, TcpFastOpen.sendEnabled))
|
||||
}
|
||||
|
||||
def refreshContainerHolder() {
|
||||
val holder = app.containerHolder
|
||||
if (holder != null) holder.refresh()
|
||||
}
|
||||
|
||||
def crashRecovery() {
|
||||
val cmd = new ArrayBuffer[String]()
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ class ShadowsocksNatService extends BaseService {
|
||||
"-t", "10",
|
||||
"-b", "127.0.0.1",
|
||||
"-l", (profile.localPort + 63).toString,
|
||||
"-L", profile.remoteDns.trim + ":53",
|
||||
"-L", profile.remoteDns.split(",").head.trim + ":53",
|
||||
"-c", buildShadowsocksConfig("ss-tunnel-nat.conf"))
|
||||
|
||||
if (profile.udpdns) cmd.append("-u")
|
||||
|
||||
@@ -22,8 +22,6 @@ package com.github.shadowsocks
|
||||
|
||||
import java.io.File
|
||||
import java.util.Locale
|
||||
import java.net.InetAddress
|
||||
import java.net.Inet6Address
|
||||
|
||||
import android.content._
|
||||
import android.content.pm.PackageManager.NameNotFoundException
|
||||
@@ -223,11 +221,8 @@ class ShadowsocksVpnService extends VpnService with BaseService {
|
||||
val subnet = Subnet.fromString(cidr)
|
||||
builder.addRoute(subnet.address.getHostAddress, subnet.prefixSize)
|
||||
})
|
||||
val addr = InetAddress.getByName(profile.remoteDns.trim)
|
||||
if (addr.isInstanceOf[Inet6Address])
|
||||
builder.addRoute(addr, 128)
|
||||
else if (addr.isInstanceOf[InetAddress])
|
||||
builder.addRoute(addr, 32)
|
||||
profile.remoteDns.split(",").map(dns => Utils.parseNumericAddress(dns.trim)).foreach(dns =>
|
||||
builder.addRoute(dns, dns.getAddress.length << 3))
|
||||
}
|
||||
|
||||
conn = builder.establish()
|
||||
|
||||
@@ -34,6 +34,7 @@ import scala.io.Source
|
||||
*/
|
||||
object AclSyncJob {
|
||||
final val TAG = "AclSyncJob"
|
||||
final val MAX_RESCHEDULE = 3
|
||||
|
||||
def schedule(route: String): Int = new JobRequest.Builder(AclSyncJob.TAG + ':' + route)
|
||||
.setExecutionWindow(TimeUnit.SECONDS.toMillis(10), TimeUnit.DAYS.toMillis(28))
|
||||
@@ -45,6 +46,8 @@ object AclSyncJob {
|
||||
}
|
||||
|
||||
class AclSyncJob(route: String) extends Job {
|
||||
var rescheduled = 0
|
||||
|
||||
override def onRunJob(params: Params): Result = {
|
||||
try {
|
||||
//noinspection JavaAccessorMethodCalledAsEmptyParen
|
||||
@@ -54,7 +57,11 @@ class AclSyncJob(route: String) extends Job {
|
||||
} catch {
|
||||
case e: IOException =>
|
||||
e.printStackTrace()
|
||||
Result.RESCHEDULE
|
||||
rescheduled += 1
|
||||
if (rescheduled < AclSyncJob.MAX_RESCHEDULE)
|
||||
Result.RESCHEDULE
|
||||
else
|
||||
Result.FAILURE
|
||||
case e: Exception => // unknown failures, probably shouldn't retry
|
||||
e.printStackTrace()
|
||||
Result.FAILURE
|
||||
|
||||
@@ -80,7 +80,9 @@ object Utils {
|
||||
def resolve(host: String, addrType: Int): Option[String] = {
|
||||
try {
|
||||
val lookup = new Lookup(host, addrType)
|
||||
val resolver = new SimpleResolver("114.114.114.114")
|
||||
val resolver = new SimpleResolver("208.67.220.220")
|
||||
resolver.setTCP(true)
|
||||
resolver.setPort(443)
|
||||
resolver.setTimeout(5)
|
||||
lookup.setResolver(resolver)
|
||||
val result = lookup.run()
|
||||
|
||||
@@ -7,3 +7,5 @@ addSbtPlugin("net.virtual-void" % "sbt-dependency-graph" % "0.8.2")
|
||||
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "1.1")
|
||||
|
||||
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.0.0") // fot sbt-0.13.5 or higher
|
||||
|
||||
addSbtPlugin("org.scala-android" % "sbt-android-gms" % "0.4")
|
||||
|
||||
Reference in New Issue
Block a user