package config import ( "encoding/json" "os" "path/filepath" ) var ( ConfigDir string SubscriptionsFile string ConfigsFile string StateFile string LogsDir string XrayDir string ) type WireGuardConfig struct { Name string `json:"name"` Config string `json:"config"` } type VLESSConfig struct { Name string `json:"name"` URL string `json:"url"` Protocol string `json:"protocol,omitempty"` Subscription string `json:"subscription,omitempty"` } type Configs struct { WireGuard []WireGuardConfig `json:"wireguard"` VLESS []VLESSConfig `json:"vless"` } type Subscription struct { Name string `json:"name"` URL string `json:"url"` } type Subscriptions struct { Subscriptions []Subscription `json:"subscriptions"` } type ConnectionState struct { Connected bool `json:"connected"` ConfigName string `json:"config_name"` ConfigType string `json:"config_type"` StartTime string `json:"start_time"` Interface string `json:"interface"` ProcessPID int `json:"process_pid"` LogFile string `json:"log_file"` } // Init инициализирует конфигурационные директории и файлы func Init() error { // Получаем рабочую директорию workDir, err := os.Getwd() if err != nil { return err } ConfigDir = filepath.Join(workDir, ".vpn_client") SubscriptionsFile = filepath.Join(ConfigDir, "subscriptions.json") ConfigsFile = filepath.Join(ConfigDir, "configs.json") StateFile = filepath.Join(ConfigDir, "state.json") LogsDir = filepath.Join(workDir, "logs") XrayDir = filepath.Join(workDir, "xray") // Создаем директории if err := os.MkdirAll(ConfigDir, 0755); err != nil { return err } if err := os.MkdirAll(LogsDir, 0755); err != nil { return err } // Инициализируем файлы если их нет if err := initFileIfNotExists(SubscriptionsFile, Subscriptions{Subscriptions: []Subscription{}}); err != nil { return err } if err := initFileIfNotExists(ConfigsFile, Configs{WireGuard: []WireGuardConfig{}, VLESS: []VLESSConfig{}}); err != nil { return err } if err := initFileIfNotExists(StateFile, ConnectionState{}); err != nil { return err } return nil } func initFileIfNotExists(path string, defaultData interface{}) error { if _, err := os.Stat(path); os.IsNotExist(err) { data, err := json.MarshalIndent(defaultData, "", " ") if err != nil { return err } return os.WriteFile(path, data, 0644) } return nil } // LoadConfigs загружает конфигурации func LoadConfigs() (*Configs, error) { data, err := os.ReadFile(ConfigsFile) if err != nil { return nil, err } var configs Configs if err := json.Unmarshal(data, &configs); err != nil { return nil, err } return &configs, nil } // SaveConfigs сохраняет конфигурации func SaveConfigs(configs *Configs) error { data, err := json.MarshalIndent(configs, "", " ") if err != nil { return err } return os.WriteFile(ConfigsFile, data, 0644) } // LoadSubscriptions загружает подписки func LoadSubscriptions() (*Subscriptions, error) { data, err := os.ReadFile(SubscriptionsFile) if err != nil { return nil, err } var subs Subscriptions if err := json.Unmarshal(data, &subs); err != nil { return nil, err } return &subs, nil } // SaveSubscriptions сохраняет подписки func SaveSubscriptions(subs *Subscriptions) error { data, err := json.MarshalIndent(subs, "", " ") if err != nil { return err } return os.WriteFile(SubscriptionsFile, data, 0644) } // LoadState загружает состояние подключения func LoadState() (*ConnectionState, error) { data, err := os.ReadFile(StateFile) if err != nil { return nil, err } var state ConnectionState if err := json.Unmarshal(data, &state); err != nil { return nil, err } return &state, nil } // SaveState сохраняет состояние подключения func SaveState(state *ConnectionState) error { data, err := json.MarshalIndent(state, "", " ") if err != nil { return err } return os.WriteFile(StateFile, data, 0644) }