feat: серверная топология е!!!!!!!!! убейте меня

This commit is contained in:
Jganenokk
2026-08-06 10:03:08 +07:00
parent 47fe58b852
commit a46ee7234c
9 changed files with 847 additions and 72 deletions
+84
View File
@@ -51,9 +51,13 @@ class Api {
int? _callsSeed;
String? _deviceId;
String? _callsDevice;
String? _callsOsVersion;
int? get callsSeed => _callsSeed;
String? get deviceId => _deviceId;
String? get callsDevice => _callsDevice;
String? get callsOsVersion => _callsOsVersion;
/// Сырой доступ к сессии ядра — для медиа-загрузок (data-plane).
KolibriSession? get session => _session;
@@ -387,6 +391,10 @@ class Api {
String instanceId = await DeviceIdentity.instanceId();
int clientSessionId = DeviceIdentity.clientSessionId;
String? androidManufacturer;
String? androidModel;
int? androidSdkInt;
if (Platform.isLinux) {
final linuxInfo = await deviceInfo.linuxInfo;
osVersion = linuxInfo.name;
@@ -398,15 +406,20 @@ class Api {
final androidInfo = await deviceInfo.androidInfo;
osVersion = 'Android ${androidInfo.version.release}';
deviceName = '${androidInfo.manufacturer} ${androidInfo.model}';
androidManufacturer = androidInfo.manufacturer;
androidModel = androidInfo.model;
androidSdkInt = androidInfo.version.sdkInt;
} else if (Platform.isWindows) {
final windowsInfo = await deviceInfo.windowsInfo;
osVersion = windowsInfo.productName;
}
String? spoofUserAgent;
final spoofed = await SpoofingService.getSpoofedSessionData(
scope: spoofScope,
);
if (spoofed != null) {
spoofUserAgent = spoofed['user_agent'] as String?;
final sDeviceType = spoofed['device_type'] as String?;
if (sDeviceType != null && sDeviceType != 'IOS') deviceType = sDeviceType;
final sDeviceName = spoofed['device_name'] as String?;
@@ -448,6 +461,19 @@ class Api {
if (sClientSession is int) clientSessionId = sClientSession;
}
_callsDevice = _resolveCallsDevice(
spoofed: spoofed != null,
deviceName: deviceName,
spoofUserAgent: spoofUserAgent,
manufacturer: androidManufacturer,
model: androidModel,
);
_callsOsVersion = _resolveCallsOsVersion(
spoofed: spoofed != null,
osVersion: osVersion,
sdkInt: androidSdkInt,
);
_userAgent = {
'deviceType': deviceType,
'appVersion': appVersion,
@@ -491,6 +517,64 @@ class Api {
);
}
static String? _resolveCallsDevice({
required bool spoofed,
required String deviceName,
String? spoofUserAgent,
String? manufacturer,
String? model,
}) {
if (!spoofed &&
manufacturer != null &&
manufacturer.isNotEmpty &&
model != null &&
model.isNotEmpty) {
return '$manufacturer/$model';
}
final parts = deviceName.trim().split(RegExp(r'\s+'))
..removeWhere((p) => p.isEmpty);
if (parts.isEmpty) return null;
final fallbackModel = parts.length > 1
? parts.sublist(1).join(' ')
: parts.first;
return '${parts.first}/'
'${_modelFromUserAgent(spoofUserAgent) ?? fallbackModel}';
}
static String? _modelFromUserAgent(String? userAgent) {
if (userAgent == null || userAgent.isEmpty) return null;
final match = RegExp(r'Android\s+[\d.]+;\s*([^;)]+)').firstMatch(userAgent);
final model = match
?.group(1)
?.replaceFirst(RegExp(r'\s+Build/.*$'), '')
.trim();
return model == null || model.isEmpty ? null : model;
}
static String _resolveCallsOsVersion({
required bool spoofed,
required String osVersion,
int? sdkInt,
}) {
if (!spoofed && sdkInt != null && sdkInt > 0) return '$sdkInt';
final release = RegExp(
r'^Android\s+(\d+)',
).firstMatch(osVersion.trim())?.group(1);
return '${_androidSdkForRelease(int.tryParse(release ?? ''))}';
}
static int _androidSdkForRelease(int? release) => switch (release) {
null => 34,
<= 9 => 28,
10 => 29,
11 => 30,
12 => 31,
13 => 33,
14 => 34,
15 => 35,
_ => 36,
};
static Future<String?> _buildProxyUrl() async {
final p = await ProxyConfig.load();
if (!p.isEnabled) return null;
+3 -2
View File
@@ -2,6 +2,7 @@ import 'dart:convert';
import 'contacts.dart';
import '../api.dart';
import '../../core/calls/ws2_signaling.dart';
import '../../core/protocol/opcode_map.dart';
import '../../core/utils/ids.dart';
import '../../core/utils/logger.dart';
@@ -178,13 +179,13 @@ class CallsModule {
String _internalParams() => jsonEncode({
'platform': 'ANDROID',
'sdkVersion': '0.1.16.4',
'sdkVersion': '0.2.1.3',
'clientAppKey': 'CGPGAGLGDIHBABABA',
'deviceId': _api.deviceId ?? '',
'protocolVersion': 5,
'onlyAdminCanRecord': false,
'isWaitForAdminEnabled': false,
'hexCapability': '3c03f',
'hexCapability': Ws2Config.defaultCapabilities,
});
Future<CallLinkPreview?> resolveCallLink(String url) async {