diff --git a/readme.md b/readme.md index 19af705..7eb01b9 100644 --- a/readme.md +++ b/readme.md @@ -245,6 +245,46 @@ DtGetNavigationBarHeight.execute(); ## 5. Tabela completa das APIs do bridge +Mapa atual dos objetos injetados: + +| Objeto nativo `Cake*` | Alias `Dt*` | Método | +|---|---|---| +| `CakeGetVpnState` | `DtGetVpnState` | `execute()` | +| `CakeGetConfigs` | `DtGetConfigs` | `execute()` | +| `CakeGetDefaultConfig` | `DtGetDefaultConfig` | `execute()` | +| `CakeSetConfig` | `DtSetConfig` | `execute(id)` | +| `CakeUsername` | `DtUsername` | `get()`, `set(value)` | +| `CakePassword` | `DtPassword` | `get()`, `set(value)` | +| `CakeUuid` | `DtUuid` | `get()`, `set(value)` | +| `CakeStartAppUpdate` | `DtStartAppUpdate` | `execute()` | +| `CakeStartUpdatePayload` | `DtStartUpdatePayload` | `execute()` | +| `CakeExecuteVpnStart` | `DtExecuteVpnStart` | `execute()` | +| `CakeExecuteVpnStop` | `DtExecuteVpnStop` | `execute()` | +| `CakeGetLogs` | `DtGetLogs` | `execute()` | +| `CakeGetLastConnectionError` | `DtGetLastConnectionError`, `DtGetConnectionError` | `execute()` | +| `CakeGetNetworkDownloadBytes` | `DtGetNetworkDownloadBytes` | `execute()` | +| `CakeGetLocalConfigVersion` | `DtGetLocalConfigVersion` | `execute()` | +| `CakeShowLoggerDialog` | `DtShowLoggerDialog` | `execute()` | +| `CakeStartCheckUser` | `DtStartCheckUser` | `execute()` | +| `CakeGetStatusHotSpotService` | `DtGetStatusHotSpotService` | `execute()` | +| `CakeStartHotSpotService` | `DtStartHotSpotService` | `execute()` | +| `CakeStopHotSpotService` | `DtStopHotSpotService` | `execute()` | +| `CakeGetLocalIP` | `DtGetLocalIP` | `execute()` | +| `CakeGetNetworkName` | `DtGetNetworkName` | `execute()` | +| `CakeGetPingResult` | `DtGetPingResult` | `execute()` | +| `CakeGetStatusBarHeight` | `DtGetStatusBarHeight` | `execute()` | +| `CakeGetNavigationBarHeight` | `DtGetNavigationBarHeight` | `execute()` | +| `CakeStartWebViewActivity` | `DtStartWebViewActivity` | `execute(url)` | +| `CakeGetAppConfig` | `DtGetAppConfig` | `execute(label)` | +| `CakeIgnoreBatteryOptimizations` | `DtIgnoreBatteryOptimizations` | `execute()` | +| `CakeStartApnActivity` | `DtStartApnActivity` | `execute()` | +| `CakeCleanApp` | `DtCleanApp` | `execute()` | +| `CakeAirplaneState` | `DtAirplaneState` | `execute()` | +| `CakeAirplaneActivate` | `DtAirplaneActivate` | `execute()` | +| `CakeAirplaneDeactivate` | `DtAirplaneDeactivate` | `execute()` | + +O helper `CakeApp` injetado nesta versão expõe somente `CakeApp.vpn`, `CakeApp.configs`, `CakeApp.auth`, `CakeApp.errors` e `CakeApp.system`. + ### 5.1 APIs de config e perfil | API | Assinatura | Retorno | Finalidade | @@ -705,28 +745,16 @@ function refreshCurrentServer() { } ``` -Depois da seleção, o app nativo também chama `CakeApp.applyAuthVisibility()` para esconder/mostrar automaticamente os campos de autenticação. +Depois da seleção, o tema deve atualizar a própria UI lendo `DtGetDefaultConfig.execute()` de novo. O bridge atual aplica a config nativamente, mas não injeta um helper automático de visibilidade. --- ## 9. Visibilidade dos campos de autenticação -O app injeta `CakeApp.applyAuthVisibility()` e executa automaticamente no carregamento e depois da seleção de config. +O bridge atual não injeta `CakeApp.applyAuthVisibility()`. O tema deve decidir a visibilidade usando: -Ele varre todos os elementos `input`, `textarea` e `select`, e classifica eles por `id`, `name`, `class`, `placeholder` e `type`. - -Ele detecta: - -- Campos de UUID quando os metadados contêm `v2ray`, `uuid`, `xray`, `vmess` ou `vless`. -- Campos de senha quando os metadados contêm `password`, `senha` ou `pass`. -- Campos de usuário quando os metadados contêm `username`, `usuario`, `login` ou tokens parecidos com usuário. - -Ele esconde o container pai mais próximo que bata com: - -```css -[data-auth-field], .form-group, .input-group, .field, .item, .row, .col, -[class*=field], [class*=input], [class*=form] -``` +- `auth.username`, `auth.password` e `auth.v2ray_uuid` vindos de `DtGetDefaultConfig.execute()`. +- `DtUsername.get()`, `DtPassword.get()` e `DtUuid.get()`, que retornam `Locked` quando aquele input manual não deve ser editado. HTML recomendado: @@ -744,11 +772,13 @@ HTML recomendado: ``` -### Detecção V2Ray/Xray/VMess/VLess nesta versão +### Detecção V2Ray/Xray/VMess/VLess no tema -No patch atual, a função injetada de visibilidade já considera `v2ray`, `xray`, `vmess` e `vless` no `mode` e também nos metadados do input. +O HTML recebe `mode` do catálogo como texto. Se o painel usa nomes como `VMESS` ou `VLESS` no catálogo, trate esses valores no helper do tema para mostrar o campo UUID. -Estes formatos são detectados como perfis baseados em UUID: +Importante: no payload real de settings aplicado nativamente, o parser do app reconhece `V2RAY`, `XRAY` ou `tunnelType: 6` como modo Xray/V2Ray. Use `VMESS`/`VLESS` como rótulos de catálogo apenas se o helper do tema também tratar esses nomes. + +O helper abaixo detecta estes formatos como perfis baseados em UUID: ```json { "mode": "V2RAY" } @@ -782,12 +812,27 @@ function isLocked(value) { return String(value ?? '').trim().toLowerCase() === 'locked'; } -function isUuidProfile(config) { +function bridgeGet(name) { + try { + const obj = window[name]; + return obj && typeof obj.get === 'function' ? obj.get() : ''; + } catch (e) { + return ''; + } +} + +function bridgeExec(name, fallback = '') { + try { + const obj = window[name]; + return obj && typeof obj.execute === 'function' ? obj.execute() : fallback; + } catch (e) { + return fallback; + } +} + +function isUuidCatalogMode(config) { const mode = String(config?.mode || '').toLowerCase(); - const auth = config?.auth || {}; - return auth.v2ray_uuid === true || - auth.manual_v2ray_uuid === true || - mode.includes('v2ray') || + return mode.includes('v2ray') || mode.includes('xray') || mode.includes('vmess') || mode.includes('vless'); @@ -795,16 +840,37 @@ function isUuidProfile(config) { function updateAuthVisibility(config = null) { if (!config) { - try { config = JSON.parse(DtGetDefaultConfig.execute() || '{}'); } + try { config = JSON.parse(bridgeExec('DtGetDefaultConfig', '{}') || '{}'); } catch (e) { config = {}; } } - const uuidRequired = isUuidProfile(config) && !isLocked(DtUuid.get?.()); - const sshRequired = !uuidRequired; + const auth = config?.auth || {}; + const uuidLocked = isLocked(bridgeGet('DtUuid')); + const usernameLocked = isLocked(bridgeGet('DtUsername')); + const passwordLocked = isLocked(bridgeGet('DtPassword')); - document.querySelector('#uuid-group').style.display = uuidRequired ? '' : 'none'; - document.querySelector('#username-group').style.display = sshRequired ? '' : 'none'; - document.querySelector('#password-group').style.display = sshRequired ? '' : 'none'; + const uuidRequired = ( + auth.v2ray_uuid === true || + auth.manual_v2ray_uuid === true || + isUuidCatalogMode(config) + ) && !uuidLocked; + + const sshRequired = ( + auth.username === true || + auth.manual_username === true || + auth.password === true || + auth.manual_password === true || + !usernameLocked || + !passwordLocked + ) && !uuidRequired; + + const uuidGroup = document.querySelector('#uuid-group'); + const usernameGroup = document.querySelector('#username-group'); + const passwordGroup = document.querySelector('#password-group'); + + if (uuidGroup) uuidGroup.style.display = uuidRequired ? '' : 'none'; + if (usernameGroup) usernameGroup.style.display = sshRequired ? '' : 'none'; + if (passwordGroup) passwordGroup.style.display = sshRequired ? '' : 'none'; } ``` @@ -1347,7 +1413,7 @@ Antes de publicar um tema, verifique: - Chama `DtSetConfig.execute(id)` antes de iniciar um perfil selecionado. - Salva usuário/senha/UUID antes de conectar. - Trata `auth.username`, `auth.password` e `auth.v2ray_uuid`. -- O campo UUID aparece para configs `mode: "V2RAY"`, `"XRAY"`, `"VMESS"` e `"VLESS"`. +- O campo UUID aparece para configs com `auth.v2ray_uuid: true`; se o catálogo usar `mode: "VMESS"` ou `"VLESS"`, o helper do tema trata esses nomes. - Se usar proxy local, confirma `DtGetStatusHotSpotService.execute()` depois de chamar start/stop. - Se usar proxy local em Android 13+, considera que a notificação pode depender da permissão `POST_NOTIFICATIONS`. - Não depende de `DtGetPingResult` retornar ping real. @@ -1356,7 +1422,7 @@ Antes de publicar um tema, verifique: --- -## 21. Resumo dos bridges novos do patch V2/V3/V4 +## 21. Resumo dos bridges novos do patch V2/V3/V4/V5 Esta versão do patch adiciona/atualiza estes pontos para temas HTML OnlineConfig: @@ -1372,7 +1438,7 @@ Esta versão do patch adiciona/atualiza estes pontos para temas HTML OnlineConfi | SSH_DIRECT com payload/proxy | logs + erro classificado | Mesmo em SSH direto, o app tenta detectar resposta HTTP inicial do proxy sem quebrar banner SSH. | | Proxy local foreground | `DtStartHotSpotService.execute()` | Inicia `ProxyService` com notificação foreground em vez de ligar apenas o socket interno. | | Permissão de notificação | abertura do `OnlineConfigWebActivity` e start do proxy | Android 13+ pede `POST_NOTIFICATIONS`; se negar, o tema deve confirmar o status do proxy. | -| Detecção UUID | `CakeApp.applyAuthVisibility()` | Agora considera `v2ray`, `xray`, `vmess` e `vless`. | +| Detecção UUID no tema | `DtGetDefaultConfig.execute()` + `DtUuid.get()` | O bridge expõe `auth.v2ray_uuid` e `Locked`; o tema decide a visibilidade, incluindo `v2ray`, `xray`, `vmess` e `vless` quando necessário. | Exemplo completo para tema tratar logs e erros: