Skip to content

Commit

Permalink
juicity v0.1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
arm64v8a committed Aug 6, 2023
1 parent e5cb171 commit 510a8fd
Show file tree
Hide file tree
Showing 7 changed files with 378 additions and 10 deletions.
18 changes: 18 additions & 0 deletions app_juicity/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}

setupAll()

android {
defaultConfig {
applicationId = "moe.matsuri.plugin.juicity"
versionCode = 1
versionName = "test-3"
splits.abi {
reset()
include("arm64-v8a", "x86_64")
}
}
}
37 changes: 37 additions & 0 deletions app_juicity/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="moe.matsuri.plugin.juicity"
android:installLocation="internalOnly">

<application
android:allowBackup="false"
android:extractNativeLibs="true"
android:label="Juicity For NekoBox">
<provider
android:name=".BinaryProvider"
android:authorities="moe.matsuri.plugin.juicity.BinaryProvider"
android:directBootAware="true"
android:exported="true"
tools:ignore="ExportedContentProvider">
<intent-filter>
<action android:name="io.nekohasekai.sagernet.plugin.ACTION_NATIVE_PLUGIN" />
</intent-filter>
<intent-filter>
<action android:name="io.nekohasekai.sagernet.plugin.ACTION_NATIVE_PLUGIN" />
<data
android:host="moe.matsuri.lite"
android:path="/moe.matsuri.plugin.juicity"
android:scheme="plugin" />
</intent-filter>

<meta-data
android:name="io.nekohasekai.sagernet.plugin.id"
android:value="moe.matsuri.plugin.juicity" />
<meta-data
android:name="io.nekohasekai.sagernet.plugin.executable_path"
android:value="libjuicity.so" />
</provider>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package moe.matsuri.plugin.juicity

import android.net.Uri
import android.os.ParcelFileDescriptor
import io.nekohasekai.sagernet.plugin.NativePluginProvider
import io.nekohasekai.sagernet.plugin.PathProvider
import java.io.File
import java.io.FileNotFoundException

class BinaryProvider : NativePluginProvider() {
override fun populateFiles(provider: PathProvider) {
provider.addPath("moe.matsuri.plugin.juicity", 0b111101101)
}

override fun getExecutable() = context!!.applicationInfo.nativeLibraryDir + "/libjuicity.so"

override fun openFile(uri: Uri): ParcelFileDescriptor = when (uri.path) {
"/moe.matsuri.plugin.juicity" -> ParcelFileDescriptor.open(
File(getExecutable()),
ParcelFileDescriptor.MODE_READ_ONLY
)
else -> throw FileNotFoundException()
}
}
35 changes: 25 additions & 10 deletions download.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,45 @@ mkdir_libs() {

unzip_xray() {
rm -rf tmp
unzip -d tmp xray.zip
unzip -d tmp tmp.zip
mv tmp/xray "$1"/libxray.so
rm -rf tmp xray.zip
rm -rf tmp tmp.zip
}

unzip_singbox() {
rm -rf tmp
mkdir tmp
tar -zxvf singbox.tar.gz -C tmp
tar -zxvf tmp.tar.gz -C tmp
mv tmp/*/sing-box "$1"/libsingbox.so
rm -rf tmp singbox.tar.gz
rm -rf tmp tmp.tar.gz
}

unzip_juicity() {
rm -rf tmp
unzip -d tmp tmp.zip
mv tmp/juicity-client "$1"/libjuicity.so
rm -rf tmp tmp.zip
}

download_xray() {
VERSION="v1.7.5"
mkdir_libs "app_xray/libs"

curl -Lso xray.zip "https://github.com/XTLS/Xray-core/releases/download/$VERSION/Xray-android-arm64-v8a.zip"
curl -Lso tmp.zip "https://github.com/XTLS/Xray-core/releases/download/$VERSION/Xray-android-arm64-v8a.zip"
unzip_xray arm64-v8a
curl -Lso xray.zip "https://github.com/XTLS/Xray-core/releases/download/$VERSION/Xray-linux-arm32-v7a.zip"
curl -Lso tmp.zip "https://github.com/XTLS/Xray-core/releases/download/$VERSION/Xray-linux-arm32-v7a.zip"
unzip_xray armeabi-v7a
curl -Lso xray.zip "https://github.com/XTLS/Xray-core/releases/download/$VERSION/Xray-linux-32.zip"
curl -Lso tmp.zip "https://github.com/XTLS/Xray-core/releases/download/$VERSION/Xray-linux-32.zip"
unzip_xray x86
curl -Lso xray.zip "https://github.com/XTLS/Xray-core/releases/download/$VERSION/Xray-linux-64.zip"
curl -Lso tmp.zip "https://github.com/XTLS/Xray-core/releases/download/$VERSION/Xray-linux-64.zip"
unzip_xray x86_64
}

download_singbox() {
mkdir_libs "app_singbox/libs"
curl -Lso singbox.tar.gz "https://github.com/SagerNet/sing-box/releases/download/v1.2-beta5/sing-box-1.2-beta5-android-arm64.tar.gz"
curl -Lso tmp.tar.gz "https://github.com/SagerNet/sing-box/releases/download/v1.2-beta5/sing-box-1.2-beta5-android-arm64.tar.gz"
unzip_singbox arm64-v8a
curl -Lso singbox.tar.gz "https://github.com/SagerNet/sing-box/releases/download/v1.2-beta5/sing-box-1.2-beta5-android-amd64.tar.gz"
curl -Lso tmp.tar.gz "https://github.com/SagerNet/sing-box/releases/download/v1.2-beta5/sing-box-1.2-beta5-android-amd64.tar.gz"
unzip_singbox x86_64
}

Expand Down Expand Up @@ -85,4 +92,12 @@ download_tuic5() {
dl_and_chmod x86_64/libtuic.so "https://github.com/MatsuriDayo/tuic/releases/download/rel/tuic-client-"$VERSION"-x86_64-linux-android"
}

download_juicity() {
VERSION="v0.1.2"
mkdir_libs "app_juicity/libs"

curl -Lso tmp.zip "https://github.com/juicity/juicity/releases/download/"$VERSION"/juicity-android-arm64.zip"
unzip_juicity arm64-v8a
}

download_"$1"
223 changes: 223 additions & 0 deletions js/plugin_juicity/juicity.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
import { util } from "../common/util.js";
import { commomClass } from "../common/common.js";
import { TR } from "../common/translate.js";

class juicityClass {
constructor() {
this.sharedStorage = {};
this.defaultSharedStorage = {};
this.common = new commomClass();
}

_initDefaultSharedStorage() {
// start of default keys
this.defaultSharedStorage.jsVersion = 1;
this.defaultSharedStorage.name = "";
this.defaultSharedStorage.serverAddress = "127.0.0.1";
this.defaultSharedStorage.serverPort = "1080";
// end of default keys
this.defaultSharedStorage.uuid = "00000000-0000-0000-0000-000000000000";
this.defaultSharedStorage.password = "";
this.defaultSharedStorage.sni = "";
this.defaultSharedStorage.allowInsecure = false;
this.defaultSharedStorage.congestionControl = "bbr";

for (var k in this.defaultSharedStorage) {
let v = this.defaultSharedStorage[k];
this.common._setType(k, typeof v);

if (!this.sharedStorage.hasOwnProperty(k)) {
this.sharedStorage[k] = v;
}
}
}

_onSharedStorageUpdated() {
// not null
for (var k in this.sharedStorage) {
if (this.sharedStorage[k] == null) {
this.sharedStorage[k] = "";
}
}
this._setShareLink();
}

// 生成并存储 share link
_setShareLink() {
var builder = util.newURL("juicity")
if (this.sharedStorage.name.isNotBlank()) builder.hash = "#" + encodeURIComponent(this.sharedStorage.name)
builder.host = util.wrapUri(this.sharedStorage.serverAddress, this.sharedStorage.serverPort)
builder.username = this.sharedStorage.uuid
builder.password = this.sharedStorage.password
if (this.sharedStorage.congestionControl.isNotBlank()) {
builder.searchParams.set("congestion_control", this.sharedStorage.congestionControl)
}
if (this.sharedStorage.sni.isNotBlank()) {
builder.searchParams.set("sni", this.sharedStorage.sni)
}
if (this.sharedStorage.allowInsecure) {
builder.searchParams.set("allow_insecure", "1")
}
this.sharedStorage.shareLink = builder.toString()
}

// UI Interface

requirePreferenceScreenConfig() {
let sb = [
{
title: TR("serverSettings"),
preferences: [
{
type: "EditTextPreference",
key: "serverAddress",
icon: "ic_hardware_router",
},
{
type: "EditTextPreference",
key: "serverPort",
icon: "ic_maps_directions_boat",
EditTextPreferenceModifiers: "Port",
},
//
{
"type": "EditTextPreference",
"key": "uuid",
"icon": "ic_baseline_person_24",
},
{
"type": "EditTextPreference",
"key": "password",
"icon": "ic_settings_password",
"summaryProvider": "PasswordSummaryProvider",
},
//
{
"type": "EditTextPreference",
"key": "sni",
"icon": "ic_action_copyright"
},
{
"type": "SwitchPreference",
"key": "allowInsecure",
"icon": "ic_notification_enhanced_encryption",
},
{
"type": "EditTextPreference",
"key": "congestionControl",
"icon": "ic_baseline_stream_24",
},
],
},
];
this.common._applyTranslateToPreferenceScreenConfig(sb, TR);
return JSON.stringify(sb);
}

// 开启设置界面时调用
setSharedStorage(b64Str) {
this.sharedStorage = util.decodeB64Str(b64Str);
this._initDefaultSharedStorage();
}

// 开启设置界面时调用
requireSetProfileCache() {
for (var k in this.defaultSharedStorage) {
this.common.setKV(k, this.sharedStorage[k]);
}
}
// 开启设置界面时调用

// 设置界面创建后调用
onPreferenceCreated() {
let this2 = this

function listenOnPreferenceChangedNow(key) {
neko.listenOnPreferenceChanged(key)
this2._onPreferenceChanged(key, this2.sharedStorage[key])
}
}

// 保存时调用(混合编辑后的值)
sharedStorageFromProfileCache() {
for (var k in this.defaultSharedStorage) {
this.sharedStorage[k] = this.common.getKV(k);
}
this._onSharedStorageUpdated();
return JSON.stringify(this.sharedStorage);
}

// 用户修改 preference 时调用
onPreferenceChanged(b64Str) {
let args = util.decodeB64Str(b64Str)
this._onPreferenceChanged(args.key, args.newValue)
}

_onPreferenceChanged(key, newValue) {
}

// Interface

parseShareLink(b64Str) {
let args = util.decodeB64Str(b64Str)

this.sharedStorage = {}
this._initDefaultSharedStorage()

var url = util.tryParseURL(args.shareLink)
if (typeof url == "string") return url // error string

var serverAddress = util.unwrapIpv6(url.hostname)
this.sharedStorage.serverAddress = serverAddress
this.sharedStorage.serverPort = url.host.replace(serverAddress, "").substringAfter(":")
this.sharedStorage.uuid = url.username
this.sharedStorage.password = url.password
this.sharedStorage.name = decodeURIComponent(url.hash.substringAfter("#"))

util.ifNotNull(url.searchParams.get("congestion_control"), (it) => {
this.sharedStorage.congestionControl = it
})
util.ifNotNull(url.searchParams.get("sni"), (it) => {
this.sharedStorage.sni = it
})
util.ifNotNull(url.searchParams.get("allow_insecure"), (it) => {
if (it == "1" || it == "true") this.sharedStorage.allowInsecure = it
})

this._onSharedStorageUpdated()
return JSON.stringify(this.sharedStorage)
}

buildAllConfig(b64Str) {
try {
let args = util.decodeB64Str(b64Str);
let ss = util.decodeB64Str(args.sharedStorage);

let configObject = {
"listen": "127.0.0.1:" + args.port,
"server": util.wrapUri(ss.serverAddress, ss.serverPort),
"uuid": ss.uuid,
"password": ss.password,
"sni": ss.sni,
"allow_insecure": ss.allowInsecure,
"congestion_control": ss.congestionControl,
"log_level": "info",
"protect_path": "protect_path"
};

let v = {};
v.nekoCommands = ["%exe%", "run", "-c", "config.json"];
v.nekoRunConfigs = [
{
name: "config.json",
content: JSON.stringify(configObject),
},
];
return JSON.stringify(v);
} catch (error) {
neko.logError(error.toString());
}
}
}

export const juicity = new juicityClass();
Loading

0 comments on commit 510a8fd

Please sign in to comment.