Release 3.8.2.12: export/import full server list as JSON.
ci / test (macos-latest) (push) Canceled after 0s
ci / test (ubuntu-latest) (push) Canceled after 0s
ci / test (windows-latest) (push) Canceled after 0s

Save and replace profiles via system file dialog; buttons after Best; prefs unchanged on import.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
M4
2026-08-01 17:51:38 +03:00
co-authored by Cursor
parent 57d719f02f
commit 8b564110d5
22 changed files with 604 additions and 22 deletions
+31
View File
@@ -629,6 +629,37 @@ func (m *Manager) DeleteProfile(name string) error {
return config.Save(m.cfgPath, *m.cfg)
}
// ExportServers writes the current profile list (with secrets) to path.
func (m *Manager) ExportServers(path string) (int, error) {
m.mu.Lock()
defer m.mu.Unlock()
return config.WriteServersFile(path, m.cfg)
}
// ImportServersReplace replaces all profiles with those from path.
// Prefs (system proxy, reconnect, subscription URL) are preserved.
func (m *Manager) ImportServersReplace(path string) (int, error) {
m.mu.Lock()
defer m.mu.Unlock()
if m.engine != nil && m.engine.Running() {
return 0, fmt.Errorf("сначала отключитесь")
}
doc, err := config.ReadServersFile(path)
if err != nil {
return 0, err
}
if err := m.cfg.ApplyServersReplace(doc); err != nil {
return 0, err
}
for i := range m.cfg.Profiles {
hysteria2.EnrichProfile(&m.cfg.Profiles[i])
}
if err := config.Save(m.cfgPath, *m.cfg); err != nil {
return 0, err
}
return len(m.cfg.Profiles), nil
}
func (m *Manager) Profiles() []config.ProfileInfo {
m.mu.Lock()
defer m.mu.Unlock()