import 'dart:convert'; import 'package:crypto/crypto.dart'; import 'package:http/http.dart' as http; class LoginResult { final bool success; final int errorId; final int userId; final String token; const LoginResult({ required this.success, required this.errorId, required this.userId, required this.token, }); } class ApiService { static const String chimeSalt = 'XcW5FW4cPArBXEk4vzKz3CIrMuA5EVVW'; static const String baseUrl = 'http://ai.sys-allnet.cn'; String chipId; ApiService({this.chipId = 'A63E-01C28055905'}); String _formatTimestamp() { final tokyo = DateTime.now().toUtc().add(const Duration(hours: 9)); final y = (tokyo.year % 100).toString().padLeft(2, '0'); final M = tokyo.month.toString().padLeft(2, '0'); final d = tokyo.day.toString().padLeft(2, '0'); final h = tokyo.hour.toString().padLeft(2, '0'); final m = tokyo.minute.toString().padLeft(2, '0'); final s = tokyo.second.toString().padLeft(2, '0'); return '$y$M$d$h$m$s'; } String _sha256(String input) { final bytes = utf8.encode(input); return sha256.convert(bytes).toString(); } String extractQRCode(String qrCodeToken) { if (qrCodeToken.length > 64) { return qrCodeToken.substring(qrCodeToken.length - 64); } return qrCodeToken; } Future login(String qrCodeToken) async { final timestamp = _formatTimestamp(); final qrCode = extractQRCode(qrCodeToken); final rawKey = chipId + timestamp + chimeSalt; final key = _sha256(rawKey).toUpperCase(); final body = jsonEncode({ 'chipID': chipId, 'openGameID': 'MAID', 'key': key, 'qrCode': qrCode, 'timestamp': timestamp, }); final response = await http .post( Uri.parse('$baseUrl/wc_aime/api/get_data'), headers: { 'Content-Type': 'application/json', 'User-Agent': 'WC_AIME_LIB', }, body: body, ) .timeout(const Duration(seconds: 15)); final obj = jsonDecode(response.body) as Map; final errorId = obj['errorID'] as int? ?? -1; final userId = obj['userID'] as int? ?? -1; final token = obj['token'] as String? ?? ''; return LoginResult( success: errorId == 0, errorId: errorId, userId: userId, token: token, ); } }