diff --git a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt index d83b8904..1db60022 100644 --- a/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt +++ b/V2rayNG/app/src/main/java/com/v2ray/ang/handler/V2rayConfigManager.kt @@ -98,36 +98,46 @@ object V2rayConfigManager { return result } - // check if tun inbound exists - val json = JsonUtil.parseString(raw) ?: return result - val inboundsJson = if (json.has("inbounds") && json.get("inbounds")?.isJsonNull == false) { - json.getAsJsonArray("inbounds") - } else { - JsonArray() - } + val json = JsonUtil.parseString(raw)?.takeIf { it.isJsonObject }?.asJsonObject ?: return result - for (i in 0 until inboundsJson.size()) { - val elem = inboundsJson.get(i) - if (elem.isJsonObject) { - val inb = elem.asJsonObject - val tag = if (inb.has("tag") && inb.get("tag")?.isJsonNull == false) inb.get("tag").asString else "" - if (tag == "tun") return result + // Check whether package names need to be replaced with UIDs + if (SettingsManager.canUseProcessRouting()) { + val rulesJson = json.get("routing")?.takeIf { it.isJsonObject }?.asJsonObject + ?.get("rules")?.takeIf { it.isJsonArray }?.asJsonArray + ?: JsonArray() + + for (elem in rulesJson) { + val rule = elem.takeIf { it.isJsonObject }?.asJsonObject ?: continue + val process = rule.get("process")?.takeIf { it.isJsonArray }?.asJsonArray ?: continue + val packages = process.mapNotNull { + it.takeIf { it.isJsonPrimitive && it.asJsonPrimitive.isString }?.asString + }.takeIf { it.isNotEmpty() } ?: continue + val uids = PackageUidResolver.packageNamesToUids(context, packages).takeIf { it.isNotEmpty() } ?: continue + + rule.add("process", JsonArray().apply { uids.forEach { add(it) } }) } } - // add tun inbound from template - val templateConfig = initV2rayConfig(context) ?: return result - val inboundTun = templateConfig.inbounds.firstOrNull { it.tag == "tun" } ?: return result - inboundTun.settings?.mtu = SettingsManager.getVpnMtu() - - // add to json - inboundsJson.add(JsonUtil.parseString(JsonUtil.toJson(inboundTun))) - if (inboundsJson.size() == 1) { - json.add("inbounds", inboundsJson) + // check if tun inbound exists + val inboundsJson = json.get("inbounds")?.takeIf { it.isJsonArray }?.asJsonArray + ?: JsonArray().also { json.add("inbounds", it) } + val tunNotExists = inboundsJson.none { elem -> + elem.isJsonObject && elem.asJsonObject.get("protocol") + ?.takeIf { it.isJsonPrimitive && it.asJsonPrimitive.isString } + ?.asString == "tun" } - val updatedRaw = JsonUtil.toJsonPretty(json) ?: return result - return ConfigResult(true, guid, updatedRaw) + if (tunNotExists) { + // add tun inbound from template + initV2rayConfig(context)?.let { templateConfig -> + templateConfig.inbounds.firstOrNull { it.tag == "tun" }?.let { inboundTun -> + inboundTun.settings?.mtu = SettingsManager.getVpnMtu() + inboundsJson.add(JsonUtil.parseString(JsonUtil.toJson(inboundTun))) + } + } + } + + return JsonUtil.toJsonPretty(json)?.let { ConfigResult(true, guid, it) } ?: result } /**