peer_model.dart 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. import 'dart:convert';
  2. import 'package:flutter/foundation.dart';
  3. import 'package:get/get.dart';
  4. import 'platform_model.dart';
  5. // ignore: depend_on_referenced_packages
  6. import 'package:collection/collection.dart';
  7. class Peer {
  8. final String id;
  9. String hash; // personal ab hash password
  10. String password; // shared ab password
  11. String username; // pc username
  12. String hostname;
  13. String platform;
  14. String alias;
  15. List<dynamic> tags;
  16. bool forceAlwaysRelay = false;
  17. String rdpPort;
  18. String rdpUsername;
  19. bool online = false;
  20. String loginName; //login username
  21. String device_group_name;
  22. bool? sameServer;
  23. String getId() {
  24. if (alias != '') {
  25. return alias;
  26. }
  27. return id;
  28. }
  29. Peer.fromJson(Map<String, dynamic> json)
  30. : id = json['id'] ?? '',
  31. hash = json['hash'] ?? '',
  32. password = json['password'] ?? '',
  33. username = json['username'] ?? '',
  34. hostname = json['hostname'] ?? '',
  35. platform = json['platform'] ?? '',
  36. alias = json['alias'] ?? '',
  37. tags = json['tags'] ?? [],
  38. forceAlwaysRelay = json['forceAlwaysRelay'] == 'true',
  39. rdpPort = json['rdpPort'] ?? '',
  40. rdpUsername = json['rdpUsername'] ?? '',
  41. loginName = json['loginName'] ?? '',
  42. device_group_name = json['device_group_name'] ?? '',
  43. sameServer = json['same_server'];
  44. Map<String, dynamic> toJson() {
  45. return <String, dynamic>{
  46. "id": id,
  47. "hash": hash,
  48. "password": password,
  49. "username": username,
  50. "hostname": hostname,
  51. "platform": platform,
  52. "alias": alias,
  53. "tags": tags,
  54. "forceAlwaysRelay": forceAlwaysRelay.toString(),
  55. "rdpPort": rdpPort,
  56. "rdpUsername": rdpUsername,
  57. 'loginName': loginName,
  58. 'device_group_name': device_group_name,
  59. 'same_server': sameServer,
  60. };
  61. }
  62. Map<String, dynamic> toCustomJson({required bool includingHash}) {
  63. var res = <String, dynamic>{
  64. "id": id,
  65. "username": username,
  66. "hostname": hostname,
  67. "platform": platform,
  68. "alias": alias,
  69. "tags": tags,
  70. };
  71. if (includingHash) {
  72. res['hash'] = hash;
  73. }
  74. return res;
  75. }
  76. Map<String, dynamic> toGroupCacheJson() {
  77. return <String, dynamic>{
  78. "id": id,
  79. "username": username,
  80. "hostname": hostname,
  81. "platform": platform,
  82. "login_name": loginName,
  83. "device_group_name": device_group_name,
  84. };
  85. }
  86. Peer({
  87. required this.id,
  88. required this.hash,
  89. required this.password,
  90. required this.username,
  91. required this.hostname,
  92. required this.platform,
  93. required this.alias,
  94. required this.tags,
  95. required this.forceAlwaysRelay,
  96. required this.rdpPort,
  97. required this.rdpUsername,
  98. required this.loginName,
  99. required this.device_group_name,
  100. this.sameServer,
  101. });
  102. Peer.loading()
  103. : this(
  104. id: '...',
  105. hash: '',
  106. password: '',
  107. username: '...',
  108. hostname: '...',
  109. platform: '...',
  110. alias: '',
  111. tags: [],
  112. forceAlwaysRelay: false,
  113. rdpPort: '',
  114. rdpUsername: '',
  115. loginName: '',
  116. device_group_name: '',
  117. );
  118. bool equal(Peer other) {
  119. return id == other.id &&
  120. hash == other.hash &&
  121. password == other.password &&
  122. username == other.username &&
  123. hostname == other.hostname &&
  124. platform == other.platform &&
  125. alias == other.alias &&
  126. tags.equals(other.tags) &&
  127. forceAlwaysRelay == other.forceAlwaysRelay &&
  128. rdpPort == other.rdpPort &&
  129. rdpUsername == other.rdpUsername &&
  130. device_group_name == other.device_group_name &&
  131. loginName == other.loginName;
  132. }
  133. Peer.copy(Peer other)
  134. : this(
  135. id: other.id,
  136. hash: other.hash,
  137. password: other.password,
  138. username: other.username,
  139. hostname: other.hostname,
  140. platform: other.platform,
  141. alias: other.alias,
  142. tags: other.tags.toList(),
  143. forceAlwaysRelay: other.forceAlwaysRelay,
  144. rdpPort: other.rdpPort,
  145. rdpUsername: other.rdpUsername,
  146. loginName: other.loginName,
  147. device_group_name: other.device_group_name,
  148. sameServer: other.sameServer);
  149. }
  150. enum UpdateEvent { online, load }
  151. typedef GetInitPeers = RxList<Peer> Function();
  152. class Peers extends ChangeNotifier {
  153. final String name;
  154. final String loadEvent;
  155. List<Peer> peers = List.empty(growable: true);
  156. final GetInitPeers? getInitPeers;
  157. UpdateEvent event = UpdateEvent.load;
  158. static const _cbQueryOnlines = 'callback_query_onlines';
  159. Peers(
  160. {required this.name,
  161. required this.getInitPeers,
  162. required this.loadEvent}) {
  163. peers = getInitPeers?.call() ?? [];
  164. platformFFI.registerEventHandler(_cbQueryOnlines, name, (evt) async {
  165. _updateOnlineState(evt);
  166. });
  167. platformFFI.registerEventHandler(loadEvent, name, (evt) async {
  168. _updatePeers(evt);
  169. });
  170. }
  171. @override
  172. void dispose() {
  173. platformFFI.unregisterEventHandler(_cbQueryOnlines, name);
  174. platformFFI.unregisterEventHandler(loadEvent, name);
  175. super.dispose();
  176. }
  177. Peer getByIndex(int index) {
  178. if (index < peers.length) {
  179. return peers[index];
  180. } else {
  181. return Peer.loading();
  182. }
  183. }
  184. int getPeersCount() {
  185. return peers.length;
  186. }
  187. void _updateOnlineState(Map<String, dynamic> evt) {
  188. int changedCount = 0;
  189. evt['onlines'].split(',').forEach((online) {
  190. for (var i = 0; i < peers.length; i++) {
  191. if (peers[i].id == online) {
  192. if (!peers[i].online) {
  193. changedCount += 1;
  194. peers[i].online = true;
  195. }
  196. }
  197. }
  198. });
  199. evt['offlines'].split(',').forEach((offline) {
  200. for (var i = 0; i < peers.length; i++) {
  201. if (peers[i].id == offline) {
  202. if (peers[i].online) {
  203. changedCount += 1;
  204. peers[i].online = false;
  205. }
  206. }
  207. }
  208. });
  209. if (changedCount > 0) {
  210. event = UpdateEvent.online;
  211. notifyListeners();
  212. }
  213. }
  214. void _updatePeers(Map<String, dynamic> evt) {
  215. final onlineStates = _getOnlineStates();
  216. if (getInitPeers != null) {
  217. peers = getInitPeers?.call() ?? [];
  218. } else {
  219. peers = _decodePeers(evt['peers']);
  220. }
  221. for (var peer in peers) {
  222. final state = onlineStates[peer.id];
  223. peer.online = state != null && state != false;
  224. }
  225. event = UpdateEvent.load;
  226. notifyListeners();
  227. }
  228. Map<String, bool> _getOnlineStates() {
  229. var onlineStates = <String, bool>{};
  230. for (var peer in peers) {
  231. onlineStates[peer.id] = peer.online;
  232. }
  233. return onlineStates;
  234. }
  235. List<Peer> _decodePeers(String peersStr) {
  236. try {
  237. if (peersStr == "") return [];
  238. List<dynamic> peers = json.decode(peersStr);
  239. return peers.map((peer) {
  240. return Peer.fromJson(peer as Map<String, dynamic>);
  241. }).toList();
  242. } catch (e) {
  243. debugPrint('peers(): $e');
  244. }
  245. return [];
  246. }
  247. }