diff --git a/backend/types.go b/backend/types.go index e358a677..cd925553 100644 --- a/backend/types.go +++ b/backend/types.go @@ -2,27 +2,28 @@ package backend // ConnectParams — параметры подключения из frontend. type ConnectParams struct { - PeerAddr string `json:"peerAddr"` // адрес:порт сервера - Password string `json:"password"` // пароль подключения - Hashes []string `json:"hashes"` // хеши VK - DeviceID string `json:"deviceId,omitempty"` // ID устройства - Workers int `json:"workers,omitempty"` // воркеры (кратно 9) + PeerAddr string `json:"peerAddr"` // адрес:порт сервера + Password string `json:"password"` // пароль подключения + Hashes []string `json:"hashes"` // хеши VK + DeviceID string `json:"deviceId,omitempty"` // ID устройства + Workers int `json:"workers,omitempty"` // воркеры (кратно 9) CaptchaMode string `json:"captchaMode,omitempty"` // auto/rjs/wv - ObfsMode string `json:"obfsMode,omitempty"` // audio/video + ObfsMode string `json:"obfsMode,omitempty"` // audio/video Fingerprint string `json:"fingerprint,omitempty"` // chrome/android/ios/safari/firefox - TurnTCP bool `json:"turnTcp,omitempty"` // использовать TCP транспорт + TurnTCP bool `json:"turnTcp,omitempty"` // использовать TCP транспорт } // ProfileData — данные сервера, хранятся в ~/.config/pwdtt/servers/.json. type ProfileData struct { - PeerAddr string `json:"peer"` // адрес:порт VPS сервера - Password string `json:"password"` // пароль подключения - Hashes []string `json:"hashes"` // хеши VK-звонков - Listen string `json:"listen"` // локальный адрес (по умолчанию 127.0.0.1:9000) - TurnHost string `json:"turn"` // переопределение IP TURN - TurnPort string `json:"port"` // переопределение порта TURN - DeviceID string `json:"device_id"` // уникальный ID устройства - TurnTCP bool `json:"turn_tcp"` // использовать TCP транспорт + PeerAddr string `json:"peer"` // адрес:порт VPS сервера + Password string `json:"password"` // пароль подключения + Hashes []string `json:"hashes"` // хеши VK-звонков + Workers int `json:"workers,omitempty"` // воркеры (кратно 9) + Listen string `json:"listen"` // локальный адрес (по умолчанию 127.0.0.1:9000) + TurnHost string `json:"turn"` // переопределение IP TURN + TurnPort string `json:"port"` // переопределение порта TURN + DeviceID string `json:"device_id"` // уникальный ID устройства + TurnTCP bool `json:"turn_tcp"` // использовать TCP транспорт } // AppSettings — настройки приложения, хранятся в ~/.config/pwdtt/config.json. diff --git a/frontend/src/__tests__/serverStore.test.ts b/frontend/src/__tests__/serverStore.test.ts index 3db397a1..5f6a8113 100644 --- a/frontend/src/__tests__/serverStore.test.ts +++ b/frontend/src/__tests__/serverStore.test.ts @@ -35,6 +35,12 @@ describe('serverStore', () => { expect(all[0].name).toBe('A'); }); + it('add: сохраняет мощность из профиля', () => { + serverStore.add({ name: 'A', host: '1.1.1.1:1111', password: 'pw', power: 18 }); + + expect(serverStore.getAll()[0].power).toBe(18); + }); + it('add: несколько серверов', () => { serverStore.add({ name: 'A', host: 'a:1', password: 'p1' }); serverStore.add({ name: 'B', host: 'b:2', password: 'p2' }); diff --git a/frontend/src/modals/Add-server.tsx b/frontend/src/modals/Add-server.tsx index aa2f7cb6..709ba2a8 100644 --- a/frontend/src/modals/Add-server.tsx +++ b/frontend/src/modals/Add-server.tsx @@ -66,6 +66,7 @@ export default function AddServer({ onClose, onAdd }: Props) { peer: host, password, hashes: hashes.filter(h => h.trim()), + workers: power, turn: '', port: '', device_id: '', @@ -138,7 +139,7 @@ export default function AddServer({ onClose, onAdd }: Props) {
- Мощность + Мощность (всего потоков) {filledHashes === 0 ? 'нет хешей' : power}
0 ? Math.round((Math.min(power, powerMax) - 9) / Math.max(powerMax - 9, 1) * 100) : 0 } as React.CSSProperties} onChange={e => setPower(+e.target.value)} - aria-label="Мощность" + aria-label="Мощность — всего потоков, шаг 9" />
diff --git a/frontend/src/modals/Edit-server.tsx b/frontend/src/modals/Edit-server.tsx index e0522b64..80afbd0f 100644 --- a/frontend/src/modals/Edit-server.tsx +++ b/frontend/src/modals/Edit-server.tsx @@ -57,6 +57,7 @@ export default function EditServer({ server, onClose, onSave, onDelete }: Props) peer: updated.host, password: updated.password, hashes, + workers: power, turn: '', port: '', device_id: '', listen: '', turn_tcp: false, }); @@ -127,7 +128,7 @@ export default function EditServer({ server, onClose, onSave, onDelete }: Props)
- Мощность + Мощность (всего потоков) {filledHashes === 0 ? 'нет хешей' : power}
0 ? Math.round((Math.min(power, powerMax) - 9) / Math.max(powerMax - 9, 1) * 100) : 0 } as React.CSSProperties} onChange={e => setPower(+e.target.value)} - aria-label="Мощность" + aria-label="Мощность — всего потоков, шаг 9" />
diff --git a/frontend/src/pages/Connect.tsx b/frontend/src/pages/Connect.tsx index 4e8cbe40..e8f161ae 100644 --- a/frontend/src/pages/Connect.tsx +++ b/frontend/src/pages/Connect.tsx @@ -216,16 +216,20 @@ export default function Connect() { ListProfiles().then(profiles => { if (!profiles) return; const existing = serverStore.getAll(); - const existingNames = new Set(existing.map(s => s.name)); - const existingHosts = new Set(existing.map(s => s.host)); let changed = false; for (const [name, p] of Object.entries(profiles)) { - if (existingNames.has(name)) continue; const host = p.peer || ''; if (!host) continue; - if (existingHosts.has(host)) continue; + const stored = existing.find(s => s.name === name || s.host === host); + if (stored) { + if (p.workers && stored.power !== p.workers) { + serverStore.update({ ...stored, power: p.workers }); + changed = true; + } + continue; + } const h4: [string,string,string,string] = [p.hashes?.[0]??'', p.hashes?.[1]??'', p.hashes?.[2]??'', p.hashes?.[3]??'']; - serverStore.add({ name, host, password: p.password ?? '', hashes: h4 }); + serverStore.add({ name, host, password: p.password ?? '', hashes: h4, power: p.workers }); changed = true; } if (changed) { @@ -287,6 +291,7 @@ export default function Connect() { peer: consumed.host, password: consumed.password, hashes: h4 as unknown as string[], + workers: consumed.workers, turn: '', port: consumed.port || '', device_id: '', listen: '', turn_tcp: false, }); const s = serverStore.add({ diff --git a/frontend/wailsjs/go/models.ts b/frontend/wailsjs/go/models.ts index b9acb7a9..258d398d 100755 --- a/frontend/wailsjs/go/models.ts +++ b/frontend/wailsjs/go/models.ts @@ -50,6 +50,7 @@ export namespace backend { peer: string; password: string; hashes: string[]; + workers?: number; listen: string; turn: string; port: string; @@ -65,6 +66,7 @@ export namespace backend { this.peer = source["peer"]; this.password = source["password"]; this.hashes = source["hashes"]; + this.workers = source["workers"]; this.listen = source["listen"]; this.turn = source["turn"]; this.port = source["port"]; diff --git a/tests/types_test.go b/tests/types_test.go index 12b14064..48aa5d9a 100644 --- a/tests/types_test.go +++ b/tests/types_test.go @@ -145,6 +145,7 @@ func TestProfileData_MarshalRoundtrip(t *testing.T) { PeerAddr: "1.2.3.4:5555", Password: "secret", Hashes: []string{"h1", "h2"}, + Workers: 18, Listen: "127.0.0.1:9000", TurnHost: "turn.example.com", TurnPort: "3478", @@ -170,6 +171,9 @@ func TestProfileData_MarshalRoundtrip(t *testing.T) { if len(got.Hashes) != 2 { t.Errorf("Hashes length: got %d, want 2", len(got.Hashes)) } + if got.Workers != p.Workers { + t.Errorf("Workers: got %d, want %d", got.Workers, p.Workers) + } if got.Listen != p.Listen { t.Errorf("Listen: got %q, want %q", got.Listen, p.Listen) } @@ -212,6 +216,7 @@ func TestProfileData_JSONTags(t *testing.T) { p := backend.ProfileData{ PeerAddr: "1.2.3.4:5555", Password: "x", + Workers: 18, DeviceID: "id", } @@ -220,7 +225,7 @@ func TestProfileData_JSONTags(t *testing.T) { json.Unmarshal(data, &raw) // Проверяем что JSON ключи соответствуют тегам - for _, key := range []string{"peer", "password", "hashes", "listen", "turn", "port", "device_id"} { + for _, key := range []string{"peer", "password", "hashes", "workers", "listen", "turn", "port", "device_id"} { if _, ok := raw[key]; !ok { t.Errorf("expected key %q in JSON output", key) } @@ -238,6 +243,7 @@ func TestProfileData_FromJSON(t *testing.T) { "peer": "5.6.7.8:443", "password": "pw", "hashes": ["a"], + "workers": 18, "listen": "0.0.0.0:1080", "turn": "1.1.1.1", "port": "8443", @@ -252,6 +258,9 @@ func TestProfileData_FromJSON(t *testing.T) { if p.PeerAddr != "5.6.7.8:443" { t.Errorf("PeerAddr: got %q", p.PeerAddr) } + if p.Workers != 18 { + t.Errorf("Workers: got %d, want 18", p.Workers) + } if p.Listen != "0.0.0.0:1080" { t.Errorf("Listen: got %q", p.Listen) }