Skip to content

Commit 8f340f0

Browse files
2dustAnGgIt886
authored andcommitted
Adding pre-proxy to group
1 parent 72a8636 commit 8f340f0

File tree

2 files changed

+108
-58
lines changed

2 files changed

+108
-58
lines changed

app/src/main/kotlin/com/neko/v2ray/util/MmkvManager.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,11 @@ object MmkvManager {
171171
removeServerViaSubid(subid)
172172
}
173173

174+
fun decodeSubscription(subscriptionId: String): SubscriptionItem? {
175+
val json = subStorage.decodeString(subscriptionId) ?: return null
176+
return Gson().fromJson(json, SubscriptionItem::class.java)
177+
}
178+
174179
fun decodeAssetUrls(): List<Pair<String, AssetUrlItem>> {
175180
val assetUrlItems = mutableListOf<Pair<String, AssetUrlItem>>()
176181
assetStorage?.allKeys()?.forEach { key ->
@@ -229,4 +234,18 @@ object MmkvManager {
229234

230235
mainStorage?.encode(KEY_ANG_CONFIGS, Gson().toJson(serverList))
231236
}
237+
238+
fun getServerViaRemarks(remarks: String?): ServerConfig? {
239+
if (remarks == null) {
240+
return null
241+
}
242+
val serverList = decodeServerList()
243+
for (guid in serverList) {
244+
val profile = decodeProfileConfig(guid)
245+
if (profile != null && profile.remarks == remarks) {
246+
return decodeServerConfig(guid)
247+
}
248+
}
249+
return null
250+
}
232251
}

app/src/main/kotlin/com/neko/v2ray/util/V2rayConfigUtil.kt

Lines changed: 89 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -16,29 +16,17 @@ import com.neko.v2ray.AppConfig.WIREGUARD_LOCAL_ADDRESS_V4
1616
import com.neko.v2ray.AppConfig.WIREGUARD_LOCAL_ADDRESS_V6
1717
import com.neko.v2ray.dto.EConfigType
1818
import com.neko.v2ray.dto.ERoutingMode
19+
import com.neko.v2ray.dto.ServerConfig
1920
import com.neko.v2ray.dto.V2rayConfig
2021
import com.neko.v2ray.dto.V2rayConfig.Companion.DEFAULT_NETWORK
2122
import com.neko.v2ray.dto.V2rayConfig.Companion.HTTP
2223

2324
object V2rayConfigUtil {
24-
private val serverRawStorage by lazy {
25-
MMKV.mmkvWithID(
26-
MmkvManager.ID_SERVER_RAW,
27-
MMKV.MULTI_PROCESS_MODE
28-
)
29-
}
30-
private val settingsStorage by lazy {
31-
MMKV.mmkvWithID(
32-
MmkvManager.ID_SETTING,
33-
MMKV.MULTI_PROCESS_MODE
34-
)
35-
}
25+
private val serverRawStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_SERVER_RAW, MMKV.MULTI_PROCESS_MODE) }
26+
private val settingsStorage by lazy { MMKV.mmkvWithID(MmkvManager.ID_SETTING, MMKV.MULTI_PROCESS_MODE) }
3627

3728
data class Result(var status: Boolean, var content: String)
3829

39-
/**
40-
* 生成v2ray的客户端配置文件
41-
*/
4230
fun getV2rayConfig(context: Context, guid: String): Result {
4331
try {
4432
val config = MmkvManager.decodeServerConfig(guid) ?: return Result(false, "")
@@ -52,16 +40,8 @@ object V2rayConfigUtil {
5240
//Log.d(ANG_PACKAGE, customConfig)
5341
return Result(true, customConfig)
5442
}
55-
val outbound = config.getProxyOutbound() ?: return Result(false, "")
56-
val address = outbound.getServerAddress() ?: return Result(false, "")
57-
if (!Utils.isIpAddress(address)) {
58-
if (!Utils.isValidUrl(address)) {
59-
Log.d(ANG_PACKAGE, "$address is an invalid ip or domain")
60-
return Result(false, "")
61-
}
62-
}
6343

64-
val result = getV2rayNonCustomConfig(context, outbound, config.remarks)
44+
val result = getV2rayNonCustomConfig(context, config)
6545
//Log.d(ANG_PACKAGE, result.content)
6646
return result
6747
} catch (e: Exception) {
@@ -70,33 +50,32 @@ object V2rayConfigUtil {
7050
}
7151
}
7252

73-
/**
74-
* 生成v2ray的客户端配置文件
75-
*/
76-
private fun getV2rayNonCustomConfig(
77-
context: Context,
78-
outbound: V2rayConfig.OutboundBean,
79-
remarks: String,
80-
): Result {
53+
private fun getV2rayNonCustomConfig(context: Context, config: ServerConfig): Result {
8154
val result = Result(false, "")
55+
56+
val outbound = config.getProxyOutbound() ?: return result
57+
val address = outbound.getServerAddress() ?: return result
58+
if (!Utils.isIpAddress(address)) {
59+
if (!Utils.isValidUrl(address)) {
60+
Log.d(ANG_PACKAGE, "$address is an invalid ip or domain")
61+
return result
62+
}
63+
}
64+
8265
//取得默认配置
8366
val assets = Utils.readTextFromAssets(context, "v2ray_config.json")
8467
if (TextUtils.isEmpty(assets)) {
8568
return result
8669
}
87-
88-
//转成Json
8970
val v2rayConfig = Gson().fromJson(assets, V2rayConfig::class.java) ?: return result
90-
91-
v2rayConfig.log.loglevel = settingsStorage?.decodeString(AppConfig.PREF_LOGLEVEL)
92-
?: "warning"
71+
v2rayConfig.log.loglevel = settingsStorage?.decodeString(AppConfig.PREF_LOGLEVEL) ?: "warning"
72+
v2rayConfig.remarks = config.remarks
9373

9474
inbounds(v2rayConfig)
9575

96-
updateOutboundWithGlobalSettings(outbound)
97-
v2rayConfig.outbounds[0] = outbound
76+
outbounds(v2rayConfig, outbound)
9877

99-
updateOutboundFragment(v2rayConfig)
78+
moreOutbounds(v2rayConfig, config.subscriptionId)
10079

10180
routing(v2rayConfig)
10281

@@ -112,16 +91,11 @@ object V2rayConfigUtil {
11291
v2rayConfig.policy = null
11392
}
11493

115-
v2rayConfig.remarks = remarks
116-
11794
result.status = true
11895
result.content = v2rayConfig.toPrettyPrinting()
11996
return result
12097
}
12198

122-
/**
123-
*
124-
*/
12599
private fun inbounds(v2rayConfig: V2rayConfig): Boolean {
126100
try {
127101
val socksPort = Utils.parseInt(
@@ -170,6 +144,20 @@ object V2rayConfigUtil {
170144
return true
171145
}
172146

147+
private fun outbounds(v2rayConfig: V2rayConfig, outbound: V2rayConfig.OutboundBean): Boolean {
148+
val ret = updateOutboundWithGlobalSettings(outbound)
149+
if (!ret) return false
150+
151+
if (v2rayConfig.outbounds.isNotEmpty()) {
152+
v2rayConfig.outbounds[0] = outbound
153+
} else {
154+
v2rayConfig.outbounds.add(outbound)
155+
}
156+
157+
updateOutboundFragment(v2rayConfig)
158+
return true
159+
}
160+
173161
private fun fakedns(v2rayConfig: V2rayConfig) {
174162
if (settingsStorage?.decodeBool(AppConfig.PREF_LOCAL_DNS_ENABLED) == true
175163
&& settingsStorage?.decodeBool(AppConfig.PREF_FAKE_DNS_ENABLED) == true
@@ -178,9 +166,6 @@ object V2rayConfigUtil {
178166
}
179167
}
180168

181-
/**
182-
* routing
183-
*/
184169
private fun routing(v2rayConfig: V2rayConfig): Boolean {
185170
try {
186171
val routingMode = settingsStorage?.decodeString(AppConfig.PREF_ROUTING_MODE)
@@ -268,12 +253,7 @@ object V2rayConfigUtil {
268253
return true
269254
}
270255

271-
private fun routingGeo(
272-
ipOrDomain: String,
273-
code: String,
274-
tag: String,
275-
v2rayConfig: V2rayConfig
276-
) {
256+
private fun routingGeo(ipOrDomain: String, code: String, tag: String, v2rayConfig: V2rayConfig) {
277257
try {
278258
if (!TextUtils.isEmpty(code)) {
279259
//IP
@@ -343,9 +323,6 @@ object V2rayConfigUtil {
343323
return domain
344324
}
345325

346-
/**
347-
* Custom Dns
348-
*/
349326
private fun customLocalDns(v2rayConfig: V2rayConfig): Boolean {
350327
try {
351328
if (settingsStorage?.decodeBool(AppConfig.PREF_FAKE_DNS_ENABLED) == true) {
@@ -668,4 +645,58 @@ object V2rayConfigUtil {
668645
}
669646
return true
670647
}
671-
}
648+
649+
private fun moreOutbounds(v2rayConfig: V2rayConfig, subscriptionId: String): Boolean {
650+
//fragment proxy
651+
if (settingsStorage?.decodeBool(AppConfig.PREF_FRAGMENT_ENABLED, false) == true) {
652+
return true
653+
}
654+
655+
if (subscriptionId.isNullOrEmpty()) {
656+
return true
657+
}
658+
try {
659+
val subItem = MmkvManager.decodeSubscription(subscriptionId) ?: return false
660+
661+
//current proxy
662+
val outbound = v2rayConfig.outbounds[0]
663+
664+
//Previous proxy
665+
val prevNode = MmkvManager.getServerViaRemarks(subItem.prevProfile)
666+
if (prevNode != null) {
667+
val prevOutbound = prevNode.getProxyOutbound()
668+
if (prevOutbound != null) {
669+
updateOutboundWithGlobalSettings(prevOutbound)
670+
prevOutbound.tag = TAG_PROXY + "2"
671+
v2rayConfig.outbounds.add(prevOutbound)
672+
outbound.streamSettings?.sockopt =
673+
V2rayConfig.OutboundBean.StreamSettingsBean.SockoptBean(
674+
dialerProxy = prevOutbound.tag
675+
)
676+
}
677+
}
678+
679+
//Next proxy
680+
val nextNode = MmkvManager.getServerViaRemarks(subItem.nextProfile)
681+
if (nextNode != null) {
682+
val nextOutbound = nextNode.getProxyOutbound()
683+
if (nextOutbound != null) {
684+
updateOutboundWithGlobalSettings(nextOutbound)
685+
nextOutbound.tag = TAG_PROXY
686+
v2rayConfig.outbounds.add(0, nextOutbound)
687+
688+
outbound.tag = TAG_PROXY + "1"
689+
nextOutbound.streamSettings?.sockopt =
690+
V2rayConfig.OutboundBean.StreamSettingsBean.SockoptBean(
691+
dialerProxy = outbound.tag
692+
)
693+
}
694+
}
695+
} catch (e: Exception) {
696+
e.printStackTrace()
697+
return false
698+
}
699+
700+
return true
701+
}
702+
}

0 commit comments

Comments
 (0)