update version

This commit is contained in:
admin
2026-06-10 22:28:22 +08:00
parent 790110de8e
commit 7962b2c976
51 changed files with 1966 additions and 1187 deletions

281
lib/utils/next_setp.dart Normal file
View File

@@ -0,0 +1,281 @@
import 'dart:convert';
import 'package:adjust_sdk/adjust.dart' show Adjust;
import 'package:flutter/foundation.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:shared_preferences/shared_preferences.dart';
import '../adjust/adjust_service.dart';
import 'device_info.dart';
import 'http_util.dart';
import 'redirect_url_resolver.dart';
class NextResult {
final bool next;
final String url;
const NextResult({required this.next, required this.url});
}
const String _appTokenInfoKey = 'last_info';
Future<AppTokenInfo?> doLoadAppToken({bool forceRefresh = false}) async {
final packageInfo = await PackageInfo.fromPlatform();
final prefs = await SharedPreferences.getInstance();
if (!forceRefresh) {
final cachedTokenInfo = AppTokenInfo.fromInfo(
_decodeCachedInfo(prefs.getString(_appTokenInfoKey)),
);
if (cachedTokenInfo != null) {
return cachedTokenInfo;
}
}
try {
final appTokenInfo = await _fetchRemoteAppToken(packageInfo);
if (appTokenInfo != null) {
await prefs.setString(_appTokenInfoKey, jsonEncode(appTokenInfo.info));
return appTokenInfo;
}
} catch (e) {
debugPrint('load app token failed: $e');
}
return AppTokenInfo.fromInfo(
_decodeCachedInfo(prefs.getString(_appTokenInfoKey)),
);
}
bool _isValidRemoteInfo(Map<String, dynamic>? info) {
if (info == null) return false;
return _isValidToken(info['e']?.toString());
}
Map<String, dynamic> _normalizeRemoteInfo(Map<String, dynamic> info) {
final normalized = Map<String, dynamic>.from(info);
normalized['e'] = normalized['e']?.toString().trim();
final facebookAppId = normalized['m']?.toString().trim();
if (facebookAppId != null && facebookAppId.isNotEmpty) {
normalized['m'] = facebookAppId;
} else {
normalized.remove('m');
}
final secret = normalized['n']?.toString().trim();
if (secret != null && secret.isNotEmpty) {
normalized['n'] = secret;
} else {
normalized.remove('n');
}
return normalized;
}
AppTokenInfo? _createAppTokenInfo(Map<String, dynamic>? info) {
if (!_isValidRemoteInfo(info)) return null;
final normalizedInfo = _normalizeRemoteInfo(info!);
return AppTokenInfo(
token: normalizedInfo['e'] as String,
i: _parseAdidTimeout(normalizedInfo['i']),
info: normalizedInfo,
);
}
class AppTokenInfo {
final String token;
final int i;
final Map<String, dynamic> info;
const AppTokenInfo({required this.token, this.i = -1, required this.info});
static AppTokenInfo? fromInfo(Map<String, dynamic>? info) {
return _createAppTokenInfo(info);
}
}
class NextStep {
String appToken = "";
String url = "";
bool resolver = true;
int i = 200;
dynamic rs;
bool _j = false;
bool get j => _j;
NextStep._();
static final NextStep I = NextStep._();
Future<void> loadAppToken() async {
final tokenInfo = await doLoadAppToken();
if (tokenInfo != null) {
appToken = tokenInfo.token;
i = tokenInfo.i;
}
await Adjust.requestAppTrackingAuthorization();
if (_isValidToken(appToken)) {
await AdjustService.instance.init(appToken);
}
// 方法不在使用,保留以兼容之前的调用
}
Future<void> loadAppInfo() async {
try {
final includeAdjust = _isValidToken(appToken);
if (!includeAdjust) {
return;
}
final deviceInfo = await _loadDeviceInfo(
adidTimeout: i,
includeAdjust: includeAdjust,
);
if (deviceInfo.isEmpty) {
return;
}
rs = await remoteInfo(jsonEncode(deviceInfo));
if (rs is! Map<String, dynamic>) return;
_applyEventMap(rs['f']);
} catch (e) {
debugPrint("loadAppInfo error $e");
}
}
Future<String> loadUrl() async {
try {
if (rs is! Map<String, dynamic>) {
return "";
}
final rawUrl = rs['b']?.toString().trim() ?? '';
_j = parseInfo(rs['j']);
return rawUrl;
} catch (_) {
return "";
}
}
}
Future<NextResult> next() async {
try {
final appTokenInfo = await doLoadAppToken();
if (appTokenInfo == null || !_isValidToken(appTokenInfo.token)) {
return const NextResult(next: true, url: '');
}
AdjustService.instance.init(appTokenInfo.token);
final deviceInfo = await _loadDeviceInfo(
adidTimeout: appTokenInfo.i,
includeAdjust: true,
);
if (deviceInfo.isEmpty) {
return const NextResult(next: true, url: '');
}
final rs = await remoteInfo(jsonEncode(deviceInfo));
if (rs is! Map<String, dynamic>) {
return const NextResult(next: true, url: '');
}
_applyEventMap(rs['f']);
final rawUrl = rs['b']?.toString().trim() ?? '';
if (rawUrl.isEmpty) {
return const NextResult(next: true, url: '');
}
final resolvedUrl = await resolveRedirectUrl(rawUrl);
return NextResult(next: false, url: resolvedUrl);
} catch (e) {
debugPrint('next step failed: $e');
return const NextResult(next: true, url: '');
}
}
Future<Map<String, dynamic>> _loadDeviceInfo({
required int adidTimeout,
bool includeAdjust = true,
}) async {
return await DeviceInfo.I.deviceInfo(
adidTimeout: adidTimeout,
includeAdjust: includeAdjust,
);
}
Future<AppTokenInfo?> _fetchRemoteAppToken(PackageInfo packageInfo) async {
final info = {};
info.addAll(<String, dynamic>{
'packageName': packageInfo.packageName,
'versionName': packageInfo.version,
'versionCode': packageInfo.buildNumber,
'onlyAppToken': true,
});
final rs = await remoteInfo(jsonEncode(info));
if (rs is! Map<String, dynamic>) return null;
final token = rs['e']?.toString().trim();
if (!_isValidToken(token)) return null;
return AppTokenInfo.fromInfo(rs);
}
Map<String, dynamic>? _decodeCachedInfo(String? value) {
if (value == null || value.isEmpty) return null;
try {
final decoded = jsonDecode(value);
if (decoded is Map<String, dynamic>) return decoded;
if (decoded is Map) return Map<String, dynamic>.from(decoded);
} catch (_) {}
return null;
}
void _applyEventMap(dynamic value) {
if (value is! Map) return;
final eventMapInfo = <String, String>{};
for (final entry in value.entries) {
final key = entry.key?.toString();
final eventToken = entry.value?.toString();
if (key != null &&
key.isNotEmpty &&
eventToken != null &&
eventToken.isNotEmpty) {
eventMapInfo[key] = eventToken;
}
}
if (eventMapInfo.isNotEmpty) {
AdjustService.instance.eventNameToToken = eventMapInfo;
}
}
bool _isValidToken(String? token) {
return token != null && token.trim().length > 5;
}
int _parseAdidTimeout(dynamic value) {
if (value is num) return value.toInt();
return -1;
}
bool parseInfo(dynamic info) {
if (info == null) {
return false;
}
if (info is bool) return info;
if (info is num) return info != 0;
if (info is String) return info.trim().toLowerCase() == "true";
return false;
}