ix_sp.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. import 'package:flutter/material.dart';
  2. import 'package:shared_preferences/shared_preferences.dart';
  3. import 'dart:convert';
  4. import '../../../config/translations/localization_service.dart';
  5. import '../../../utils/crypto.dart';
  6. import '../../../utils/log/logger.dart';
  7. import '../../constants/keys.dart';
  8. import '../models/disconnect_domain.dart';
  9. import '../models/launch/launch.dart';
  10. import '../models/launch/upgrade.dart';
  11. import '../models/launch/user.dart';
  12. class IXSP {
  13. // prevent making instance
  14. IXSP._();
  15. // get storage
  16. static late SharedPreferences _sharedPreferences;
  17. // STORING KEYS
  18. /// Key for storing the device ID
  19. static const String _deviceIdKey = 'omon_device_id';
  20. static const String _fcmTokenKey = 'fcm_token';
  21. static const String _currentLocalKey = 'current_local';
  22. static const String _lightThemeKey = 'is_theme_light';
  23. static const String _launchGame = 'is_launch_game';
  24. static const String _ignoreVersionKey = 'ignore_version';
  25. static const String _isNewInstallKey = 'is_new_install';
  26. static const String _launchDataKey = 'launch_data';
  27. //记录网络报错的域名信息
  28. static const String _disconnectDomainsKey = 'disconnect_domains';
  29. //记录最后一次是否是地区禁用
  30. static const String _isRegionDisabledKey = 'is_region_disabled';
  31. //记录最后一次是否是用户禁用
  32. static const String _isUserDisabledKey = 'is_user_disabled';
  33. //记录最后一次是否是设备禁用
  34. static const String _isDeviceDisabledKey = 'is_device_disabled';
  35. //记录最后一次上传的性能日志boostSessionId
  36. static const String _lastMetricsLogKey = 'last_metrics_log';
  37. //记录最后一次上传的es日志boostSessionId
  38. static const String _lastESLogKey = 'last_es_log';
  39. //记录是否开启debug log
  40. static const String _enableDebugLogKey = 'enable_debug_log';
  41. //记录是否开启ping 0默认 1开启 2关闭
  42. static const String _enablePingModeKey = 'enable_ping_mode';
  43. /// init get storage services
  44. static Future<void> init() async {
  45. _sharedPreferences = await SharedPreferences.getInstance();
  46. }
  47. static setStorage(SharedPreferences sharedPreferences) {
  48. _sharedPreferences = sharedPreferences;
  49. }
  50. /// set theme current type as light theme
  51. static Future<void> setThemeIsLight(bool lightTheme) =>
  52. _sharedPreferences.setBool(_lightThemeKey, lightTheme);
  53. /// get if the current theme type is light
  54. static bool getThemeIsLight() =>
  55. _sharedPreferences.getBool(_lightThemeKey) ??
  56. true; // todo set the default theme (true for light, false for dark)
  57. /// save current locale
  58. static Future<void> setCurrentLanguage(String languageCode) =>
  59. _sharedPreferences.setString(_currentLocalKey, languageCode);
  60. /// get current locale
  61. static Locale getCurrentLocal() {
  62. String? langCode = _sharedPreferences.getString(_currentLocalKey);
  63. // default language is english
  64. if (langCode == null) {
  65. return LocalizationService.defaultLanguage;
  66. }
  67. return LocalizationService.supportedLanguages[langCode]!;
  68. }
  69. /// save generated fcm token
  70. static Future<void> setFcmToken(String token) =>
  71. _sharedPreferences.setString(_fcmTokenKey, token);
  72. /// get authorization token
  73. static String getFcmToken() =>
  74. _sharedPreferences.getString(_fcmTokenKey) ?? '';
  75. /// set launch game
  76. static Future<void> setLaunchGame(bool isLaunch) =>
  77. _sharedPreferences.setBool(_launchGame, isLaunch);
  78. /// get launch game
  79. static bool getLaunchGame() =>
  80. _sharedPreferences.getBool(_launchGame) ?? false;
  81. /// clear all data from shared pref
  82. static Future<void> clear() async => await _sharedPreferences.clear();
  83. /// Save unique ID to shared preferences
  84. static Future<void> setDeviceId(String deviceId) =>
  85. _sharedPreferences.setString(_deviceIdKey, deviceId);
  86. /// Get unique ID from shared preferences
  87. static String? getDeviceId() => _sharedPreferences.getString(_deviceIdKey);
  88. /// Save ignore version to shared preferences
  89. static Future<void> setIgnoreVersion(int version) =>
  90. _sharedPreferences.setInt(_ignoreVersionKey, version);
  91. /// Get ignore version from shared preferences
  92. static int getIgnoreVersion() =>
  93. _sharedPreferences.getInt(_ignoreVersionKey) ?? 0;
  94. /// Save is new install to shared preferences
  95. static Future<void> setIsNewInstall(bool isNewInstall) =>
  96. _sharedPreferences.setBool(_isNewInstallKey, isNewInstall);
  97. /// Get is new install from shared preferences
  98. static bool getIsNewInstall() =>
  99. _sharedPreferences.getBool(_isNewInstallKey) ?? true;
  100. /// 保存 DisconnectDomain 列表,合并 domain+status 相同的数据
  101. static Future<void> addDisconnectDomain(DisconnectDomain newItem) async {
  102. try {
  103. final prefs = _sharedPreferences;
  104. // 读取已存在的数据
  105. final oldJson = prefs.getString(_disconnectDomainsKey);
  106. List<DisconnectDomain> allList = [];
  107. if (oldJson != null && oldJson.isNotEmpty) {
  108. final List<dynamic> oldList = jsonDecode(oldJson);
  109. allList = oldList.map((e) => DisconnectDomain.fromJson(e)).toList();
  110. }
  111. // 合并新旧数据
  112. allList.add(newItem);
  113. // 按 domain+status 分组合并
  114. final Map<String, DisconnectDomain> merged = {};
  115. for (var item in allList) {
  116. final key = '${item.domain}_${item.status}';
  117. if (!merged.containsKey(key)) {
  118. merged[key] = DisconnectDomain(
  119. domain: item.domain,
  120. status: item.status,
  121. msg: item.msg,
  122. startTime: item.startTime,
  123. endTime: item.endTime,
  124. count: item.count,
  125. );
  126. } else {
  127. final exist = merged[key]!;
  128. exist.startTime = exist.startTime < item.startTime
  129. ? exist.startTime
  130. : item.startTime;
  131. exist.endTime = exist.endTime > item.endTime
  132. ? exist.endTime
  133. : item.endTime;
  134. exist.count += item.count;
  135. // msg 以最新的为准
  136. exist.msg = item.msg;
  137. }
  138. }
  139. // 保存合并后的数据
  140. final mergedList = merged.values.toList();
  141. await prefs.setString(
  142. _disconnectDomainsKey,
  143. jsonEncode(mergedList.map((e) => e.toJson()).toList()),
  144. );
  145. } catch (e) {
  146. log('IVSP', 'addDisconnectDomain error: $e');
  147. }
  148. }
  149. /// 读取 DisconnectDomain 列表
  150. static List<DisconnectDomain> getDisconnectDomains() {
  151. final jsonStr = _sharedPreferences.getString(_disconnectDomainsKey);
  152. if (jsonStr == null || jsonStr.isEmpty) return [];
  153. final List<dynamic> list = jsonDecode(jsonStr);
  154. return list.map((e) => DisconnectDomain.fromJson(e)).toList();
  155. }
  156. /// 清空 DisconnectDomain 列表
  157. static Future<void> clearDisconnectDomains() async {
  158. await _sharedPreferences.remove(_disconnectDomainsKey);
  159. }
  160. // 记录最后一次是否是用户禁用
  161. static Future<void> setLastIsUserDisabled(bool isUserDisabled) async {
  162. await _sharedPreferences.setBool(_isUserDisabledKey, isUserDisabled);
  163. }
  164. // 获取最后一次是否是用户禁用
  165. static bool getLastIsUserDisabled() {
  166. return _sharedPreferences.getBool(_isUserDisabledKey) ?? false;
  167. }
  168. // 记录最后一次是否是地区禁用
  169. static Future<void> setLastIsRegionDisabled(bool isRegionDisabled) async {
  170. await _sharedPreferences.setBool(_isRegionDisabledKey, isRegionDisabled);
  171. }
  172. // 获取最后一次是否是地区禁用
  173. static bool getLastIsRegionDisabled() {
  174. return _sharedPreferences.getBool(_isRegionDisabledKey) ?? false;
  175. }
  176. // 记录最后一次是否是设备禁用
  177. static Future<void> setLastIsDeviceDisabled(bool isDeviceDisabled) async {
  178. await _sharedPreferences.setBool(_isDeviceDisabledKey, isDeviceDisabled);
  179. }
  180. // 获取最后一次是否是设备禁用
  181. static bool getLastIsDeviceDisabled() {
  182. return _sharedPreferences.getBool(_isDeviceDisabledKey) ?? false;
  183. }
  184. /// Save last metrics log
  185. static Future<void> setLastMetricsLog(String log) async {
  186. await _sharedPreferences.setString(_lastMetricsLogKey, log);
  187. }
  188. /// Get last metrics log
  189. static String getLastMetricsLog() =>
  190. _sharedPreferences.getString(_lastMetricsLogKey) ?? '';
  191. /// Save last es log
  192. static Future<void> setLastESLog(String log) async {
  193. await _sharedPreferences.setString(_lastESLogKey, log);
  194. }
  195. /// Get last es log
  196. static String getLastESLog() =>
  197. _sharedPreferences.getString(_lastESLogKey) ?? '';
  198. /// Save enable debug log
  199. static Future<void> setEnableDebugLog(bool enable) async {
  200. await _sharedPreferences.setBool(_enableDebugLogKey, enable);
  201. }
  202. /// Get enable debug log
  203. static bool getEnableDebugLog() =>
  204. _sharedPreferences.getBool(_enableDebugLogKey) ?? false;
  205. /// Save enable ping
  206. static Future<void> setEnablePingMode(int model) async {
  207. await _sharedPreferences.setInt(_enablePingModeKey, model);
  208. }
  209. /// Get enable ping
  210. static int getEnablePingMode() =>
  211. _sharedPreferences.getInt(_enablePingModeKey) ?? 0;
  212. /// 保存 Launch 数据
  213. static Future<bool> saveLaunch(Launch launch) async {
  214. try {
  215. final jsonData = jsonEncode(launch.toJson());
  216. // 保存数据
  217. await _sharedPreferences.setString(
  218. _launchDataKey,
  219. Crypto.encrypt(jsonData, Keys.aesKey, Keys.aesIv),
  220. );
  221. // 保存保存时间
  222. log('IXSP', 'Launch data saved successfully');
  223. return true;
  224. } catch (e) {
  225. log('IXSP', 'Error saving launch data: $e');
  226. return false;
  227. }
  228. }
  229. /// 获取 Launch 数据
  230. static Launch? getLaunch() {
  231. try {
  232. final jsonData = _sharedPreferences.getString(_launchDataKey);
  233. if (jsonData == null) {
  234. return null;
  235. }
  236. final Map<String, dynamic> map = jsonDecode(
  237. Crypto.decrypt(jsonData, Keys.aesKey, Keys.aesIv),
  238. );
  239. return Launch.fromJson(map);
  240. } catch (e) {
  241. log('IXSP', 'Error getting launch data: $e');
  242. return null;
  243. }
  244. }
  245. /// 获取用户信息
  246. static User? getUser() {
  247. final launch = getLaunch();
  248. return launch?.userConfig;
  249. }
  250. /// 获取升级信息
  251. static Upgrade? getUpgrade() {
  252. final launch = getLaunch();
  253. return launch?.upgradeConfig;
  254. }
  255. /// 保存用户信息
  256. static Future<void> saveUser(User user) async {
  257. final launch = getLaunch();
  258. final newLaunch = launch!.copyWith(userConfig: user);
  259. await saveLaunch(newLaunch);
  260. }
  261. /// 清除 Launch 数据
  262. static Future<bool> clearLaunchData() async {
  263. try {
  264. await _sharedPreferences.remove(_launchDataKey);
  265. log('IXSP', 'Launch data cleared');
  266. return true;
  267. } catch (e) {
  268. log('IXSP', 'Error clearing launch data: $e');
  269. return false;
  270. }
  271. }
  272. /// 通用获取字符串方法
  273. static String? getString(String key) {
  274. return _sharedPreferences.getString(key);
  275. }
  276. /// 通用设置字符串方法
  277. static Future<bool> setString(String key, String value) async {
  278. try {
  279. return await _sharedPreferences.setString(key, value);
  280. } catch (e) {
  281. log('IXSP', 'Error setting string for key $key: $e');
  282. return false;
  283. }
  284. }
  285. }