diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml index 9cfbced..48a9ee9 100644 --- a/.github/workflows/android.yml +++ b/.github/workflows/android.yml @@ -6,25 +6,27 @@ jobs: build: runs-on: ubuntu-latest steps: - - name: Code Checkout - uses: actions/checkout@v1 + - name: Checkout + uses: actions/checkout@v3 - name: Extract Signature run: echo ${{secrets.KEY_FILE}} | base64 -d > $HOME/.android.jks - - name: set up JDK 1.8 - uses: actions/setup-java@v1 + - name: set up JDK 11 + uses: actions/setup-java@v3 with: - java-version: 1.8 + java-version: '11' + distribution: 'temurin' + cache: gradle - name: Build with Gradle run: ./gradlew assembleRelease env: KEY_PASS: ${{secrets.KEY_PASS}} - name: Upload artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3.1.1 with: name: ShadowsocksGostPlugin.apk path: app/build/outputs/apk/release/app-release.apk - name: Release Build - uses: meeDamian/github-release@1.0 + uses: meeDamian/github-release@2.0 with: token: ${{secrets.GITHUB_TOKEN}} draft: true diff --git a/README.md b/README.md index a4c1c84..dc20894 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +

Looking for maintainer 本项目正在寻求接手维护者

+

Welcome to Shadowsocks Gost Plugin

GitHub Workflow Status @@ -29,14 +31,14 @@ Download prebuilt APK here [Release](https://github.com/xausky/ShadowsocksGostPl ## ❗ 注意 Notices -* 使用#SS_HOST参数会先对填写的主机名进行DNS解析后才传递 -* 如果是与主机名相关的远程协议比如ws协议必须直接在参数里配置域名 -* 在参数里面配置的域名会忽略手机系统的DNS配置固定使用 Public DNS+ +* ~使用#SS_HOST参数会先对填写的主机名进行DNS解析后才传递~ 这应该是旧版Shadowsocks-Android才会存在的问题 +* ~如果是与主机名相关的远程协议比如ws协议必须直接在参数里配置域名~ 同上 +* 在参数里面配置的域名会忽略手机系统的DNS配置,默认使用 Public DNS+解析 * ~如果插件参数里面使用 `-F=` 形式的参数传递则后续参数不能含有 `=` 号,推荐使用 `-F ` 形式代替~ 使用新版配置格式(CFGBLOB)即可避开这个问题 -* Host specified by #SS_HOST will be firstly resolved with DNS before being passed on -* If the hostname is tied to the protocol, like WebSocket (ws), you must directly use domain name in configuration parameters -* The domain name(s) appeared in configuration parameters is/are hard-coded to be resolved with Public DNS+, in other words, ignoring the OS's DNS configurations +* ~Host specified by #SS_HOST will be firstly resolved with DNS before being passed on~ Should be a problem specific to older versions of Shadowsocks-Android +* ~If the hostname is tied to the protocol, like WebSocket (ws), you must directly use domain name in configuration parameters~ Same as above +* The domain name(s) appeared in configuration parameters is/are resolved with Public DNS+ by default, in other words, ignoring the OS's DNS configurations * ~If you configure a parameter in the form of `-F=`, then the subsequent parameters can no longer contain `=`, so it's recommended to use the form of `-F ` instead~ This issue can be avoided simply by using new config format (CFGBLOB) ## ❤ 关注我 Follow me diff --git a/app/build.gradle b/app/build.gradle index aed0908..25b72b2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,7 +7,7 @@ android { minSdkVersion 21 targetSdkVersion 29 versionCode 2111 - versionName "2.11.1" + versionName "3.0.0-rc.0" } signingConfigs { releaseConfig { diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000..f92a4e3 Binary files /dev/null and b/app/src/main/ic_launcher-playstore.png differ diff --git a/app/src/main/java/com/github/shadowsocks/plugin/gost/ConfigActivity.java b/app/src/main/java/com/github/shadowsocks/plugin/gost/ConfigActivity.java index ff3f66f..daac8e2 100644 --- a/app/src/main/java/com/github/shadowsocks/plugin/gost/ConfigActivity.java +++ b/app/src/main/java/com/github/shadowsocks/plugin/gost/ConfigActivity.java @@ -2,11 +2,14 @@ import android.annotation.SuppressLint; import android.app.AlertDialog; +import android.content.ContentResolver; import android.content.Context; import android.content.ContextWrapper; import android.content.DialogInterface; +import android.content.Intent; import android.content.res.ColorStateList; import android.graphics.Color; +import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.text.Editable; @@ -23,6 +26,7 @@ import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.github.shadowsocks.plugin.ConfigurationActivity; import com.github.shadowsocks.plugin.PluginOptions; @@ -31,15 +35,19 @@ import org.json.JSONException; import org.json.JSONObject; +import java.io.BufferedReader; import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; +import java.util.Objects; import java.util.Set; -import java.util.regex.Matcher; public class ConfigActivity extends ConfigurationActivity { private LinearLayout linearlayout_cmdargs; @@ -349,6 +357,7 @@ private void addFileEntry(final String fileName, final String fileData, String h @SuppressLint("InflateParams") final View child = inflater.inflate(R.layout.fileentry, null); TextView fileNameLabel = child.findViewById(R.id.text_file_name); + Button button_load = child.findViewById(R.id.button_load); Button button_del_file = child.findViewById(R.id.button_del_file); EditText fileDataEditText = child.findViewById(R.id.editText_file_data); @@ -364,6 +373,13 @@ private void addFileEntry(final String fileName, final String fileData, String h fileDataMap.put(fileName, fileDataEditText.getText()); + button_load.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + readFromFile(fileName); + } + }); + button_del_file.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { @@ -374,8 +390,74 @@ public void onClick(View v) { parent.addView(child); } + private static final int READ_FROM_FILE = 1; + private String openingFileName = ""; + private void readFromFile(String openingFileName) { + if (readFileThread != null && readFileThread.isAlive()) { + showToast(R.string.still_reading); + return; + } + this.openingFileName = openingFileName; + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + String mimeType = "*/*"; + if (openingFileName.endsWith(".json")) + mimeType = "application/json"; + else if (openingFileName.endsWith(".pem")) + mimeType = "application/x-pem-file"; + else if (openingFileName.endsWith(".txt")) + mimeType = "text/plain"; + intent.setType(mimeType); + startActivityForResult(intent, READ_FROM_FILE); + } + + private Thread readFileThread; + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + if (requestCode == READ_FROM_FILE) { + if (data != null) { + final Uri uri = data.getData(); + final ContentResolver resolver = this.getContentResolver(); + if (readFileThread == null || !readFileThread.isAlive()) { + readFileThread = new Thread() { + @Override + public void run() { + try { + StringBuilder stringBuilder = new StringBuilder(); + InputStream inputStream = resolver.openInputStream(uri); + BufferedReader reader = new BufferedReader(new InputStreamReader(Objects.requireNonNull(inputStream))); + char[] buf = new char[4096]; + for (int r, t = 0; (r = reader.read(buf)) != -1; t += r) { + if (t > 1024 * 1024) { + showToast(R.string.err_file_too_large); + return; + } + stringBuilder.append(buf, 0, r); + } + final String result = stringBuilder.toString(); + runOnUiThread(new Runnable() { + @Override + public void run() { + Editable editable = fileDataMap.get(openingFileName); + if (editable != null) { + editable.clear(); + editable.append(result); + } + } + }); + } catch (IOException ignored) {} + } + }; + readFileThread.start(); + } else Log.e("ConfigActivity", "readFileThread is unexpectedly alive"); + } + } else { + super.onActivityResult(requestCode, resultCode, data); + } + } + private final String[] fileNameList = { - "config.json", + "config.yaml", "cacert.pem", "clientcert.pem", "clientcertkey.pem", @@ -420,6 +502,18 @@ private void saveUI() throws NullPointerException, JSONException { } this.decodedPluginOptions.put("Files", files); + // save DNS server + EditText editText_dns_server = findViewById(R.id.editText_dns_server); + Editable editable_dns_server = editText_dns_server.getText(); + String dnsServer = ""; + if (editable_dns_server != null) { + dnsServer = editable_dns_server.toString(); + } + if (dnsServer.length() == 0) { + dnsServer = getString(R.string.example_dns_server); + } + this.decodedPluginOptions.put("DNSServer", dnsServer); + // save legacyCfg, if there's one String legacyCfg = ""; EditText editText_legacyCfg = findViewById(R.id.editText_legacyCfg); @@ -496,6 +590,17 @@ private void populateUI() throws JSONException { addFileEntry(fileName, jsonObject.getString(fileName), "", true); } + // populate dns server + String dnsServer = ""; + try { + dnsServer = this.decodedPluginOptions.getString("DNSServer"); + } catch (JSONException ignored) {} + if (dnsServer.length() == 0) { + dnsServer = getString(R.string.example_dns_server); + } + EditText editText_dns_server = findViewById(R.id.editText_dns_server); + editText_dns_server.setText(dnsServer); + // populate legacyCfg, if there's one String legacyCfg = ""; try { diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index 1f6bb29..0000000 --- a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml deleted file mode 100644 index 0d025f9..0000000 --- a/app/src/main/res/drawable/ic_launcher_background.xml +++ /dev/null @@ -1,170 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/app/src/main/res/layout/config_activity.xml b/app/src/main/res/layout/config_activity.xml index 978b992..8f56d39 100644 --- a/app/src/main/res/layout/config_activity.xml +++ b/app/src/main/res/layout/config_activity.xml @@ -163,6 +163,37 @@ android:textStyle="bold" /> + + + + + + -