Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
a3eedcb
Rebrand to InvisibleGorilla, fix critical bugs, add build script
hvkeyn Feb 17, 2026
304ddd8
Fix VPN proxy not routing traffic, add gorilla branding, update repo …
hvkeyn Feb 17, 2026
0886134
Fix app hang on disconnect, update README with fork improvements
hvkeyn Feb 17, 2026
e8c2e60
img upload
hvkeyn Feb 17, 2026
3fad61b
Merge pull request #1 from hvkeyn/rebrand/invisible-gorilla
hvkeyn Feb 17, 2026
7a7ec7c
feat(build): auto-install GCC, add download progress and reliability
hvkeyn Feb 17, 2026
2b1ea6b
feat(build): auto-install GCC, add download progress and reliability
hvkeyn Feb 17, 2026
b622caf
Merge branch 'feature/build-auto-deps-and-progress' of https://github…
hvkeyn Feb 17, 2026
fbade91
MacOS build sxript
hvkeyn Feb 17, 2026
e0a1149
feat(macos): add standalone CLI binary and update build script
hvkeyn Feb 18, 2026
0583038
feat(macos): port GUI to macOS using Avalonia UI
hvkeyn Feb 18, 2026
35fa475
fix(macos): localization, window close behavior, config context menu
hvkeyn Feb 18, 2026
747c727
Merge pull request #2 from hvkeyn/feature/macos-avalonia-gui
hvkeyn Feb 18, 2026
ec28f71
fix(macos): resolve localization, window lifecycle, UI interaction is…
hvkeyn Feb 19, 2026
33c605b
Merge pull request #3 from hvkeyn/fix/macos-gui-improvements
hvkeyn Feb 19, 2026
36b7f1a
fix(macos): fix Check crash, Quit hang, and minimize button
hvkeyn Feb 19, 2026
98c68ed
Merge pull request #4 from hvkeyn/fix/macos-gui-improvements
hvkeyn Feb 19, 2026
17d6371
fix(macos): fix dialog re-opening loop, window lifecycle, minimize
hvkeyn Feb 19, 2026
c5c9279
Merge pull request #5 from hvkeyn/fix/macos-gui-improvements
hvkeyn Feb 19, 2026
1f9e478
Update build file
hvkeyn Feb 19, 2026
d2d7a0e
fix(macos): fix broken close/minimize by removing min/max constraints
hvkeyn Feb 20, 2026
d653768
chore: remove temp file
hvkeyn Feb 20, 2026
4b9deae
Merge branch 'fix/macos-gui-improvements' - macOS GUI fixes round 3
hvkeyn Feb 21, 2026
87951f8
docs: rewrite README as user-oriented guide with screenshots
hvkeyn Feb 21, 2026
9593e66
Fix TUN startup flow and build integration for InvisibleGorilla-TUN
hvkeyn Mar 13, 2026
fed927b
Fix TUN startup flow and package TUN runtime with the client
hvkeyn Mar 15, 2026
1c5977a
Add experimental Android APK support and auto-install build prerequis…
hvkeyn Mar 26, 2026
13466cb
Improve Android config flows and add x86_64 emulator runtime support
hvkeyn Mar 27, 2026
fc4b3ad
Redesign the Android server management
hvkeyn Mar 27, 2026
7a3740a
Apply Windows app icon to Android and add live connection status noti…
hvkeyn Mar 27, 2026
647a801
Update Android branding and release APKs for arm64 and x64
hvkeyn Mar 27, 2026
67addd3
Implement Android VpnService routing and stabilize VPN teardown
hvkeyn Mar 28, 2026
a6fa044
Fix Android VPN lifecycle, config checks, share flow, and status noti…
hvkeyn Mar 28, 2026
6c81511
Android, Windows and Mac update functional list and cross-platform ap…
hvkeyn Mar 28, 2026
bcf52a8
Update android_tun2socks.go
hvkeyn Mar 28, 2026
8dcf2b2
Implement three-mode app rules with shared templates across Android, …
hvkeyn Mar 30, 2026
48d03a8
Fix Android app rules editor initialization and Manage flow
hvkeyn Mar 30, 2026
9602f48
Fix Android app picker tap handling and show app icons
hvkeyn Mar 31, 2026
1d3e2d7
Secure local TUN bridge with authenticated SOCKS and sanitized raw co…
hvkeyn Apr 7, 2026
dbf8018
Add Linux head (ALT Linux + GNOME) reusing macOS Avalonia views with …
hvkeyn Apr 19, 2026
3d3fbfc
bash build for Alt Linux
hvkeyn Apr 20, 2026
3f8acc6
Fix Linux build packaging and runtime paths
Apr 25, 2026
7df0d37
Fix Windows build SDK bootstrap
hvkeyn Apr 25, 2026
43fe54f
Fix dotnet install SDK version argument
hvkeyn Apr 25, 2026
2296f6c
Limit Windows build script to desktop project
hvkeyn Apr 25, 2026
d83854d
Add config export format options.
hvkeyn Apr 25, 2026
1e0536d
Fix config-data link import.
hvkeyn Apr 25, 2026
e6e6eaa
Improve Linux bundle launchers.
hvkeyn Apr 27, 2026
84996e5
Document Linux build support.
hvkeyn Apr 28, 2026
a49f0a6
Handle Windows build file locks.
hvkeyn Apr 28, 2026
b30b241
Fix Linux dotnet fallback path.
hvkeyn Apr 28, 2026
03b9d74
Improve ALT Linux build fallback.
hvkeyn May 2, 2026
e273d59
Fix Linux SDK bootstrap.
hvkeyn May 3, 2026
7ed1207
Merge pull request #6 from hvkeyn/fix/linux-global-json-sdk
hvkeyn May 3, 2026
6443606
Use local dotnet SDK fallback.
hvkeyn May 3, 2026
07ab48f
Isolate Linux dotnet restore state.
hvkeyn May 3, 2026
3cb0f32
fix(macos): SDK from global.json, dist-macos bundle, clearer errors
hvkeyn May 5, 2026
09a5bda
fix(macos): keep user data outside app bundle
hvkeyn May 5, 2026
e5c5d24
fix(android): add diagnostic log sharing and harden whitelist mode
hvkeyn May 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
32 changes: 32 additions & 0 deletions .cursorrules
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Invisible Gorilla XRay Client Notes

- Всегда читать все файлы из `memory-bank/` в начале новой задачи. Если Memory Bank отсутствует, создать базовые файлы и поддерживать их в актуальном состоянии.
- Всегда отвечать пользователю на русском языке.
- Для Android VPN/TUN изменений проверять не только UI, но и реальную маршрутизацию через IP-проверку в браузере до и после `STOP`.
- После правок в `XRay-Wrapper/xray/android_tun2socks.go` обязательно пересобирать `libXRayCore.so` для `arm64-v8a` и `x86_64`.
- После правок в Android runtime/service публиковать как минимум `android-x64` для эмулятора и `android-arm64` для устройства.
- Для Android нативная библиотека должна идти через `AndroidNativeLibrary`, а не через копирование `.bin` в app-private storage.
- В `InvisibleGorilla-XRay.Android/Views/MainView.axaml.cs` для сложных overlay/dialog контролов не полагаться на auto-generated поля `x:Name`; на Android они могут оставаться `null` в runtime. Для обращений из code-behind использовать явные `GetRequiredControl(...)`-геттеры с именами, не совпадающими с `x:Name`.
- Если на Android проявляется зависание при `STOP`, сначала проверять блокировки вокруг `StopAndroidTun2Socks`, `AndroidVpnService`, `OnStartCommand`, `StopForeground`, и `logcat` на `Timeout executing service` или `ANR`.
- Для сложных `vless://` ссылок в adb помнить, что `&` и `#` могут ломаться shell-парсингом; при необходимости валидировать через прямую запись конфига в app data или через UI/clipboard flow.
- Для установки и runtime-проверки Android-сборок на эмуляторе использовать `Release` APK; `dotnet publish -c Debug` может давать fast-deployment APK с падением `No assemblies found ... Assuming this is part of Fast Deployment`.
- В `XRay-Wrapper/xray/android_tun2socks.go` нельзя занулять `bridge.tunFile`/`bridge.lwip` до завершения `runAndroidTunLoop`; корректный shutdown: закрыть `stop`, закрыть TUN FD, дождаться `bridge.done`, затем закрывать LWIP, иначе `STOP` может уронить Android процесс через Go panic `nil pointer dereference`.
- В Windows-сборке `InvisibleGorilla-XRay` runtime-пути (`Settings.json`, `TUN`, `Libraries`) завязаны на текущую рабочую директорию (`.`), а не на переназначаемый `SetRoot()`, поэтому любые desktop runtime-проверки вне UI нужно запускать с правильным `cwd`.
- В `InvisibleGorilla-XRay.Mac/Views` использовать абсолютные `using InvisibleGorillaXRay.Services...`, потому что после добавления `InvisibleGorillaXRay.Mac.Services` относительные `using Services...` начинают резолвиться не в тот namespace.
- Desktop app rules хранятся как полный список выбранных приложений; при сохранении настроек нужно сохранять и те выбранные rules, которые временно не попали в auto-discovery список, чтобы не терять скрытые/редкие приложения.
- В Avalonia-представлениях Android не называть собственные свойства/геттеры так же, как `x:Name` в `.axaml`: `Avalonia.NameGenerator` уже создаёт поля с этими именами, и совпадение приводит к `CS0102` при сборке.
- Исключения приложений в Android через `VpnService.Builder.AddDisallowedApplication(...)` меняют маршрут трафика, но не гарантируют, что сторонние приложения не увидят сам факт активной VPN-сессии; в Windows/macOS текущая реализация split tunneling тоже не делает TUN/VPN полностью невидимым на уровне ОС.
- Для TUN-режима локальный SOCKS listener теперь должен идти только через session-scoped auth contract (`InvisibleGorillaXRayCore` -> `XRayCoreWrapper` -> native `XRay-Wrapper` -> Android/desktop helper); не откатывать Android или desktop TUN path обратно на `NO_AUTH`. Desktop `system proxy` path пока сознательно остаётся legacy-веткой до отдельной совместимой реализации.
- При сохранении raw JSON-конфигов через `GeneralConfig` сначала санитизировать runtime-managed top-level секции (`api`, `stats`, `inbounds`), чтобы импорт не мог подменять локальные listener/API surface, который клиент должен контролировать сам.
- Linux-голова `InvisibleGorilla-XRay.Linux` намеренно не дублирует UI: Avalonia views и code-behind линкуются из `InvisibleGorilla-XRay.Mac/`. При линковке `.axaml` файлов в `.csproj` обязательно одновременно включать их и в `<AvaloniaResource>` (для runtime XAML loading), и в `<AdditionalFiles>` с дочерним `<SourceItemGroup>AvaloniaXaml</SourceItemGroup>` — без этой метаданной Avalonia name source generator пропускает связанные XAML и сборка валится сериями `CS0103: Имя "<controlName>" не существует в текущем контексте` для всех `x:Name`-полей.
- В Linux-голове linked code-behind остаётся в namespace `InvisibleGorillaXRay.Mac.Views`; не переименовывать namespace при копировании/линковке. Любая Linux-специфичная логика идёт в отдельные файлы (`Managers/`, `Handlers/`, `Factories/`).
- `MacInstalledAppDiscovery` для Linux лежит в `InvisibleGorilla-XRay.Linux/Services/MacInstalledAppDiscovery.cs`, но под namespace `InvisibleGorillaXRay.Mac.Services`, чтобы линкованный App Rules UI цеплялся к Linux `.desktop`-парсеру без правок самих view-файлов.
- Linux TUN режим всегда fail-closed: privileged шаги (`ip tuntap`, `ip route`, `resolvectl`) идут через `pkexec` (предпочтительно) или `sudo -n`; если elevation не удался — TUN не поднимается, а не «продолжаем без VPN».
- На Linux GNOME proxy управляется только через `gsettings org.gnome.system.proxy*`. На не-GNOME окружениях `LinuxProxy` должен no-op'ом не ломая остальной flow; не пытаться поднять KDE/`environment.d` без отдельной задачи.
- Для Linux сборок единственная поддерживаемая точка входа — `./build.sh` в корне репо. При добавлении новых runtime-зависимостей обновлять и список deps в `build.sh`, и заметки в `memory-bank/techContext.md`.
- Linux app-rules сейчас только JSON-bridge (`LinuxAppRulesBridge`), без kernel enforcement (cgroups + `iptables -m owner`). Не помечать enforcement как готовый, пока не добавлен helper, реально применяющий правила на ядре.
- Для Linux native bridge имя файла обязано быть `Libraries/libXRayCore.so`: `XRayCoreWrapper` на Linux ищет именно это имя. Не собирать/копировать его как `XRayCore.so`, иначе приложение соберётся, но упадёт при первом обращении к native Xray core.
- Linux publish должен давать реальный single-file app binary `publish-linux/<rid>/InvisibleGorilla-XRay.Linux` (`PublishSingleFile=true`, `IncludeNativeLibrariesForSelfExtract=true`). Bundle-этап должен проверять именно этот исполняемый файл, а не наличие `.dll`.
- Linux `tun2socks` нужно запускать по `InvisibleGorillaXRay.Values.Path.TUN_EXE` (`AppContext.BaseDirectory/TUN/tun2socks`), а не через относительный `./TUN/tun2socks`: `.desktop` запуск не гарантирует текущую рабочую директорию `bin/`.
- Windows `build.ps1` должен читать требуемый .NET SDK из `global.json` и устанавливать/проверять именно эту версию (сейчас `8.0.419`). Нельзя считать установленный SDK 7.x достаточным: `dotnet restore` всё равно упадёт из-за SDK resolution по `global.json`.
- Windows `build.ps1` по умолчанию должен restore/build/publish только `InvisibleGorilla-XRay/InvisibleGorilla-XRay.csproj`, а не весь `InvisibleGorilla-XRay.sln`: иначе на чистой Windows-машине сборка desktop-клиента требует Android workload из `InvisibleGorilla-XRay.Android.csproj`.
25 changes: 25 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Force LF for shell scripts and other POSIX-sensitive text files so CRLF
# line endings never sneak in via Windows editors or `core.autocrlf=true`.
# This is required for build.sh and any other *.sh helpers to run on Linux.
*.sh text eol=lf
*.bash text eol=lf
build.sh text eol=lf
install.sh text eol=lf
run-igxray text eol=lf

# Linux desktop integration files are plain-text with LF endings.
*.desktop text eol=lf
*.service text eol=lf
*.policy text eol=lf

# Avalonia / .NET text assets — keep cross-platform friendly defaults.
*.cs text
*.csproj text
*.sln text
*.axaml text
*.xaml text
*.xml text
*.json text
*.yaml text
*.yml text
*.md text
2 changes: 1 addition & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1 +1 @@
custom: https://invisiblemanvpn.github.io/donation/
custom: https://invisiblegorilla.github.io/donation/
42 changes: 39 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,42 @@
/Files
/InvisibleMan-XRay/bin
/InvisibleMan-XRay/obj
/InvisibleGorilla-XRay/bin
/InvisibleGorilla-XRay/obj
/InvisibleGorilla-XRay.Mac/bin
/InvisibleGorilla-XRay.Mac/obj
/InvisibleGorilla-XRay.Android/bin
/InvisibleGorilla-XRay.Android/obj
/InvisibleGorilla-XRay.Linux/bin
/InvisibleGorilla-XRay.Linux/obj
/InvisibleGorilla-XRay.Linux/TUN
/InvisibleGorilla.Core/bin
/InvisibleGorilla.Core/obj
*.dll
*.dat
*.exe
*.exe
*.dylib
*.so

# Build outputs
/publish
/publish-android
/publish-linux
/publish-macos
/dist
/dist-linux
/dist-macos
/.dotnet-sdk
/.dotnet-home
/.nuget
/XRay-Wrapper/gorilla-xray
.cursorrules
memory-bank/activeContext.md
memory-bank/progress.md
memory-bank/systemPatterns.md
.cursorrules
.cursorrules
/memory-bank
.cursorrules
/memory-bank
.cursorrules
/memory-bank
/memory-bank
Binary file modified Images/image-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified Images/image-2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions InvisibleGorilla-XRay.Android/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk android:minSdkVersion="24" android:targetSdkVersion="34" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<queries>
<intent>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent>
</queries>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher_windows"
android:label="Invisible Gorilla XRay"
android:roundIcon="@drawable/ic_launcher_windows"
android:supportsRtl="true">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="io.invisiblegorilla.xray.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>
8 changes: 8 additions & 0 deletions InvisibleGorilla-XRay.Android/App.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="InvisibleGorillaXRay.Android.App"
RequestedThemeVariant="Dark">
<Application.Styles>
<FluentTheme />
</Application.Styles>
</Application>
86 changes: 86 additions & 0 deletions InvisibleGorilla-XRay.Android/App.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using System;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Avalonia.Threading;

namespace InvisibleGorillaXRay.Android
{
using InvisibleGorillaXRay.Android.Handlers;
using InvisibleGorillaXRay.Android.Managers;
using InvisibleGorillaXRay.Android.Platforms;
using InvisibleGorillaXRay.Android.Views;

public partial class App : Application
{
private AndroidAppManager? appManager;

public override void Initialize()
{
try
{
AvaloniaXamlLoader.Load(this);
InvisibleGorillaXRay.Core.DiagnosticLog.Write("AndroidApp", "App.Initialize: AvaloniaXamlLoader.Load completed");
}
catch (Exception ex)
{
InvisibleGorillaXRay.Core.DiagnosticLog.WriteException("AndroidApp.Initialize", ex);
throw;
}
}

public override void OnFrameworkInitializationCompleted()
{
try
{
if (ApplicationLifetime is ISingleViewApplicationLifetime singleView)
{
InvisibleGorillaXRay.Core.DiagnosticLog.Write("AndroidApp", "Single view lifetime detected");

AndroidAppStorage.ConfigureAppRoot();
InvisibleGorillaXRay.Core.DiagnosticLog.Write(
"AndroidApp",
$"App root configured: {InvisibleGorillaXRay.Values.Directory.ROOT}");

AndroidAppStorage.EnsureRuntimeAssets();
InvisibleGorillaXRay.Core.DiagnosticLog.Write("AndroidApp", "Runtime assets prepared");

appManager = new AndroidAppManager();
InvisibleGorillaXRay.Core.DiagnosticLog.Write("AndroidApp", "App manager created");

appManager.Initialize();
InvisibleGorillaXRay.Core.DiagnosticLog.Write("AndroidApp", "App manager initialized");

MainView mainView = new MainView();
InvisibleGorillaXRay.Core.DiagnosticLog.Write("AndroidApp", "MainView constructed");

singleView.MainView = mainView;
InvisibleGorillaXRay.Core.DiagnosticLog.Write("AndroidApp", "MainView assigned to lifetime");

Dispatcher.UIThread.Post(() =>
{
try
{
appManager.HandlersManager
.GetHandler<AndroidLocalizationHandler>()
.TryApplyCurrentLanguage();
mainView.Setup(appManager);
InvisibleGorillaXRay.Core.DiagnosticLog.Write("AndroidApp", "MainView setup completed");
}
catch (Exception ex)
{
InvisibleGorillaXRay.Core.DiagnosticLog.WriteException("AndroidApp.SetupPost", ex);
}
}, DispatcherPriority.ApplicationIdle);
}
}
catch (Exception ex)
{
InvisibleGorillaXRay.Core.DiagnosticLog.WriteException("AndroidApp", ex);
throw;
}

base.OnFrameworkInitializationCompleted();
}
}
}
Binary file not shown.
Loading